home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
LSD Docs
/
LSD Docs.iso
/
FILEZ
/
lsd32.dms
/
lsd32.adf
/
AmigaGfx6.pp
/
AmigaGfx6
Wrap
Text File
|
1990-09-07
|
221KB
|
6,268 lines
_________________________________________________________________________
/#########################################################################\
|#####...####..######..######......####...####..#####..##......##......###|
|####.....###..######..########..#####.....###...####..##..######..#######|
|###..###..##..######..########..####..###..##....###..##..######..#######|
|###..###..##..######..########..####..###..##..#...#..##..######......###|
|###.......##..######..########..####.......##..##.....##..######..#######|
|###..###..##..######..########..####..###..##..###....##..######..#######|
|###..###..##...#####...#######..####..###..##..####...##..######..#######|
|###..###..##......##......##......##..###..##..#####..##......##......###|
|#########################################################################|
|####################################################################{RB}#|
|=========================================================================|
| |
| ----> PRESENTS <---- |
| |
| AMIGA GRAPHICS INSIDE AND OUT - THE COMPLETE BOOK |
| |
| > PART 6 < |
| |
| Typed / Scanned / Edited By : RAZOR BLADE. |
| Additional Typing by : GLITCH ( + 8 pages by Asterix ! ). |
| Original Supplied by : VIPER |
| |
|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|
| CALL THE ALLIANCE WORLD HQ -> THE PLACE TO BE |
| UNKNOWN PLEASURES --> +44 (0) 823 322 891 --> SYSOP: BARBARIAN |
|_________________________________________________________________________|
-----------------------------------------------------------------------------
18.3 AnimObs and AnimComps
Displaying only "static" bobs isn't very exciting. Because of this, a
special animation system was created specifically for bobs. At the
beginning of this C language section, you learned one method of animation
called "color cycling" or color animation. We cycled, or scrolled, the colors
in the color registers. The contents of the preceding register were
exchanged for the contents of the current register, etc.
You also learned a second type of animation. When you moved your bobs and
vsprites they were also animated. You may be thinking that a
Commodore 64 is also able to do this. Although this is true, the Amiga is
also capable of animating bobs using the operating system software and
drawing a bob in different sequences without any commands.
The Amiga can recognise Animation Objects called AnimObs. We define
AnimObs with AnimationComponents, which are named AnimComps. The AnimComps
contain our defined bobs. For example, you could create the flight of a
seagull with different bob sequences. Then you could link these bobs with
the AnimComps and create an AnimOb.
The first step of this process is to create all your bobs as you usually do.
In addition to the flags, you must determine how the bob is written into
the bit-map (OVERLAY, SAVEBACK, etc.) and set the bobs
PAGE 479
-----------------------------------------------------------------------------
BOBISCOMP flag. This tells the animation software that your bob is an
animation component. You must also tell the system to which animation
component your bob belongs. To do this, set the pointer Bob.BobComp for
the corresponding Animcomp structure. Each animated bob requires its
own AnimComp structure.
To link the AnimComps together, use the pointers AnimComp.NextComp and
AnimComp.PrevComp. These two pointers point to the previous and next
AnimComps. Be careful because When you create a loop here it should
point only to a single AnimComp. Also, for all other AnimComps, you must
set these pointers to zero. If you don't do this, the system will think
that an AnimComp in the sequence points to a second bird instead of to the
one now animated.
Next there is the pointers NextSeq and PrevSeq. From one position you can
define many positions (as bobs) and then have the animation system page
through your sequences. This is similar to the old "Thumb movie books"
which simulated animation when you rapidly paged through a series of
pictures. Each new page of the bob creates the animation effect.
The next step is to set the sequence to cycle the pages. The pointers
NextSeq and PrevSeq point to the next and previous page or AnimComp.
These pointers create a closed ring. This means that you connect all the
AnimComps to each other with the pointers NextSeq and PrevSeq. The
previous AnimComp for the first AnimComp is the last AnimComp.
The next AnimComp from the last AnimComp is the first AnimComp.
PAGE 480
-----------------------------------------------------------------------------
Setting the RINGTRIGGER flag in the AnimComps(AnimComp.Flags = RINGTRIGGER),
which defines the ring, klls the system to flip the pages for the different
AnimComps. You can also set the length of time a specific AnimComp should be
displayed.
The variable AnimComp.TimeSet determines for how many Animate calls the
AnimComp will remain visible (Animate is the system routine that uses the
AnimObs). Animate copies the variable TimeSet to the variable Timer at the
beginning of a sequence. Timer is decremented with each Animate. Whenever
Timer equals zero, the next AnimComp in the sequence is displayed.
Now we will continue to define AnimComps and AnimObs. Just as a bob must
know which AnimComp it belongs to, the AnimComp must also know which bob it
represents. To accomplish this we point the AnimComp.AnimBob poinkr to the
specific bob.
To add something special, you can also specify one of your own routines
that will be executed each time you call Animate to display your AnimComps.
The pointer AnimComp.AnimCRoutine points to your function. Simply set this
pointer to zero when you haven't
PAGE 481
-----------------------------------------------------------------------------
defined a function. When using this function you must remember that it
returns a word value to your program. This value is not passed to the
system. Because this declaration affects the AnimComp structure, you should
check the returned value for any warning from the compiler.
Similar to the collision routines that are used with vsprites and bobs,
your functions can use the current AnimComp structure. For example, they
can check for a position and determine a specific action, or determine
object distances and react.
We are almost finished with our discussion of the AnimComp structure. But
before we explain our last point, we will discuss the AnimOb structure .
The AnimOb structure can contain many sequence rings. For example, it can
contain the arms, legs, body and the head of a man. All of these are
connected to each other and are able to move independently. We define the
components as a ring sequence which is automatically sequenced by Animate.
We represent the body with a single AnimComp structure because the body
itself usually does not move while walking.
The two pointers PrevComp and NextComp point to the AnimComps that display
the front and back view of the man. To link the AnimComps with the AnimOb
we use another pointer in the AnimOb structure. The pointer AnimOb.HeadComp
poinls to the first AnimComp that contains the rest of the objects.
(You link the components together with PrevComp and NextComp). Each
AnimComp contains a pointer back to the AnimOb. The pointer AnimComp.HeadOb
always points to the AnimOb in which the AnimComps are included.
This way you can easily access, with your routines, the required AnimOb
through the AnimComp structure.
However, more is required in order to initialise an animOb structure.
We still must determine where the structure will appear on the scrcen.
To solve this problem we use the variables Animob.Anx and AnimOb.AnY.
You cannot specify a coordinate using, for example, 160,100.
To specify the Animob coordinates, you must use a type of fixed decimal
method. The lower six bits are positioned after (to the right of) the decimal
point. To position your Animob you must multiply the RastPort coordinate
by 64.
You may be wondering why we are using such a strange positioning method.
However, remember that these variables set not only the objects' position
but also the velocity.
With each call of Animate the values from AnimOb.XAccel and AnimOb.YAccel
(X/Y movement) are added to AnimOb.XVel and
PAGE 482
-----------------------------------------------------------------------------
AnimOb.YVel (speed). The speed is then added to the position set by
AnimOb.Anx and AnimOb.AnY.
Using normal pixel values for position, speed, and movement could make your
Animob race across the screen. However, it wouldn't be very useful to have
Animob that disappears from the screen after the fifth call to Animate.
To prevent this, an Animob is moved only one pixel for every 64.
At first, it seems like this will be a problem. Multiplying by 64 is
possible, but using normal methods to move our Animob anywhere in
a RastPort presents a challenge. For the positions (Anx and Any) we have #
only 16 bits available. Normally this would provide values from -32768 to
+32768. But dividing this value by 64, gives us a range of -512 to +512.
So in order to position an object at an X coordinate of 629 in a hi-res
RastPort we have to use a trick instead of the normal methods.
We can now explain the last feature of AnimComps. It is possible to specify
the position of the individual animation components relative to animation
objects (also in steps of 64).
When you use an offset of 128*64 in AnimComp.XTrans for your animation
components you can reach any coordinate on the screen. Set positions smaller
than 128 (values between -128 and zero) in AnimOb.AnX. Values between -512
and +512 for the Y position work in any resolution. To set your components
relative Y positions, use the variable AnimComp.YTrans.
Two other variables that can be used to position an object are RingxTrans
and RingYTrans. Simply add, wilhout any changes, the value of these variables
to the current position. If you do not require any speed or motion, just
set the corresponding AnimOb variables(Xvel, YVel, XAccel and YAccel ) equal
to zero. Then initialise RingXTrans and RingYTrans with your desired values.
Make sure your speed is uniform otherwise it will affect your animation
sequences. You must synchronize the internal movements of an object
(like the wings of a bird or rotation of a wheel) with any position changes.
For example, the rotation of a wheel being slower than the forward movement
as you increase the forward speed and the wheel always rotates at the same
speed.
You can also specify a routine for your animation object that is called by
Animate. The poinler for this routine is named AnimORoutine. It is also of
the type word and you must specify the AnimOb, not the component
PAGE 483
-----------------------------------------------------------------------------
Now that we have initialised all the animation structures, the bob,
the component and the object, the only thing left to do is to display it on
the screen.
Again we need a completely initialised GelsInfo structure used for bobs and #
linked with a RastPort.
By using AddAnimOb(&AnimOb,&Key,&RastPort) we add all bobs and components of
the AnimOb to the GelsInfo structure. A required entry named Key is simply a
pointer to an AnimOb (struct AnimOb *Key = 0) that must be set to zero for
the first AddAnimOb call.
Because a list doesn't exist for the Animobs, you must know which AnimOb was
entered last in the GEL list. This helps ensure that the objects have been
properly linked. Also link the Animobs together by using the Animob.PrevOb
and AnimOb.NextOb pointers. The Key always points to the last entered Animob.
AddAnimOb handles more than linking the objects and entering the bobs in the
GEL list. It also sets the Timer variable for the AnimComps to the value
previously set in TimeSet. This permits decrementing the Timer.
Once you have processed all of the Animobs wilh AddAnimOb you are ready to
begin. Call Animate and the Timer variable for the current AnimComps is
decremented. When Timer == 0 the next sequence is activated. The position
controlled by RingXTrans, RingYTrans, Xvel, YVel, XAccel, YAccel, Xtrans and
YTrans is Calculated and then used lo display the next bob.
When you call SortGList and DrawGList as usual, your AninObs are displayed on
the screen.
18.3.1 Collisions with AnimObs
Because the smallest element used to display AnimObs are bobs, you can also
use them for collision control. Set the HitMask and Memask in the vsprite
structure of the bobs (using the same values for all bobs in one AnimComp
loop). Then you use SetCollision with your routine and test for collisions.
We have provided another example program so that you can actually see what
happens. This animation displays a flying seagull with flapping wings
(in one Animob):
PAGE 484
-----------------------------------------------------------------------------
/****************************************************************/
/* LetsAnimate.c */
/* */
/* This program displays and moves an Amiga AmimOb */
/* (here a Segull and uses AnmiComps (different */
/* wing positions */
/* Compiled with Aztec C V3.6a */
/* cc +L -S LetsAnimate.c */
/* ln LetsAnimate.o -1c32 */
/* (c) Program by Bruno Jennrich, Idea and Artwork by */
/* my little sister Ute. */
/****************************************************************/
#include "exec/types.h"
#include "exec/memory.h"
#include "exec/devices.h"
#include "devices/keymap.h"
#include "graphics/gfx.h"
#include "graphics/gfxmacros.h"
#include "graphics/copper.h"
#include "graphics/gels.h"
#include "graphics/gfxbase.h"
#include "graphics/regions.h"
#include "hardware/blit.h"
#include "hardware/custom.h"
#include "intuition/intuition.h"
#include "intuition/intuitionbase.h"
#include "libraries/diskfont.h"
#include "hardware/dmabits.h"
extern WORD MoveSeagull(); /*User AnimOb-Routine */
/* extern WORD Comp(); Optional AnimComp Routine */
#define RP Screen->RastPort /* Pointer to RastPort */
#define MAXBOBS 8 /* Seagull in in 8 Positions */
#define MAXCOORDS (MAXBOBS*2-2) /* Sequence consists of */
/* 14 pictures: 8 'to' */
/* and 6 'back'. */
struct GfxBase *GfxBase; /* BasePointer */
struct IntuitionBase *IntuitionBase;
struct NewScreen NewScreen = /* User Screen */
{
0,0,640,200,1,
1,0,
HIRES,
CUSTOMSCREEN,
NULL,
"",
NULL,NULL
};
struct Screen *Screen;
struct VSprite Start, Ende, /* VSprites for GEL */
BobsVSprite[MAXCOMPS]; /*List and Bobs */
struct Bob Bobs [MAXCOMPS]; /* User Bobs */
/* Note: 6 Bobs have the*/
/* same image!!! */
PAGE 485
-----------------------------------------------------------------------------
UWORD *BobBuffer;
/* MAXBOBS Bobs, 20 Lines of 3 WORDs for */
/* one BitPlane */
/* memory area for SAVEBACK */
/* In this example one buffer */
/* is enough, but because of */
/* the principle and to simply */
/* use new and other Bobs, */
/* we have given each Bob a */
/* 'SaveBuffer' */
UWORD *BobMask; /* Bob collisions-Masks */
/* Memory */
/* (20 Lines * 3 Words) */
UWORD BobBorderLine[MAXCOMPS][3]; /* Bobs Borderline */
/* Memory */
/* logical OR of all */
/* Bob lines in one */
/* line (here:3 Words) */
/*extern struct Custom custom; in custom.h */
/* pointer to Hardware */
/* Register for Copper */
struct UCopList *UCopList; /* own Copper List */
struct AnimComp AnimComp[MAXCOMPS];
/* seagull 'back and forth */
/* bit Start (Sequence 1) and */
/* end position (Sequence8) */
/* appear in each sequence */
/* only once, not twice */
/* like the other positions */
/* for the Seagull */
struct AnimOb *HeadOb = 0, /* Animations Key */
Seagull; /* our Seagull */
struct GelsInfo GelsInfo; /* GelsInfo initialization */
/* must be completed before */
/* using the Animation */
/* routine! */
UWORD *Image,*Help;
UWORD BobImage[MAXBOBS][20][3] =
{{
{0x0080,0x0000,0x0100}, /* Data for */
{0x0080,0x0000,0x0100}, /* Bob1. Only one */
{0x00c0,0x0000,0x0300}, /* BitPlane per */
{0x0040,0x0000,0x0200}, /* Bob */
{0x0060,0x0000,0x0600},
{0x0030,0x0000,0x0c00}, /* Please use the */
{0x0010,0x0000,0x0800}, /* copy function */
{0x0018,0x0000,0x1800}, /* of your editor */
{0x000c,0x0000,0x3000}, /* and save */
{0x0004,0x0000,0x2000}, /* yourself a lot */
{0x0006,0x0000,0x6000}, /* of work! */
{0x0003,0x0000,0xc000},
{0x0001,0x8001,0x8000},
{0x0000,0xc003,0x0000},
{0x0000,0x700e,0x0000},
PAGE 486
-----------------------------------------------------------------------------
{0x0000,0x1c38,0x0000}, /* Here is where */
{0x0000,0x0660,0x0000}, /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob2. Only one */
{0x0200,0x0000,0x0040}, /* BitPlane. */
{0x0100,0x0000,0x0080},
{0x0080,0x0000,0x0100},
{0x0060,0x0000,0x0600},
{0x0030,0x0000,0x0c00},
{0x0018,0x0000,0x1800},
{0x000c,0x0000,0x3000},
{0x0006,0x0000,0x6000},
{0x0003,0x0000,0xc000},
{0x000l,0x8001,0x8000},
{0x0000,0xe007,0x0000},
{0x0000,0x300c,0x0000},
{0x0000,0x1818,0x0000},
{0x0000,0x0c30,0x0000}, /* Here is where */
{0x0000,0x0660,0x0000}, /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob3. Only one */
{0x0000,0x0000,0x0000}, /* BitPlane. */
{0x0f00,0x0000,0x00f0},
{0x00c0,0x0000,0x0300},
{0x0060,0x0000,0x0600},
{0x0018,0x0000,0x1800},
{0x0006,0x0000,0x6000},
{0x0003,0x0000,0xc000},
{0x0001,0x8001,0x8000},
{0x0000,0x4002,0x0000},
{0x0000,0x2004,0x0000},
{0x0000,0x1008,0x0000},
{0x0000,0x0810,0x0000},
{0x0000,0x0c30,0x0000},
{0x0000,0x0660,0x0000}, /* Here is where */
{0x0000,0x0240,0x0000}, /* the data */
{0x0000,0x03c0,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob4. Only one */
{0x0000,0x0000,0x0000}, /* BitPlane. */
{0x0000,0x0000,0x0000},
{0x3000,0x0000,0x000c},
{0x0f80,0x0000,0x01f0},
{0x0070,0x0000,0x0e00},
{0x000c,0x0000,0x3000},
{0x0003,0x0000,0xc000},
{0x0001,0x8001,0x8000},
{0x0000,0x6006,0x0000},
PAGE 487
-----------------------------------------------------------------------------
{0x0000,0x300c,0x0000},
{0x0000,0x1818,0x0000},
{0x0000,0x0c30,0x0000},
{0x0000,0x0420,0x0000},
{0x0000,0x0240,0x0000}, /* Here is where */
{0x0000,0x03c0,0x0000}, /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob5. Only one */
{0x0000,0x0000,0x0000}, /* BitPlane. */
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x7ff0,0x0000,0x0ffe},
{0x800f,0x0000,0x7001},
{0x0003,0x8001,0xc000},
{0x0000,0xc003,0x0000},
{0x0000,0x2004,0x0000},
{0x0000,0x1818,0x0000},
{0x0000,0x0810,0x0000},
{0x0000,0x0420,0x0000},
{0x0000,0x0660,0x0000},
{0x0000,0x0240,0x0000}, /* Here is where */
{0x0000,0x0180,0x0000}, /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob6. Only one */
{0x0000,0x0000,0x0000}, /* BitPlane, */
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x07e0,0x0000,0x07e0},
{0x3c3e,0x0000,0x7c3c},
{0x4003,0x8001,0xc001},
{0x0000,0x6006,0x0000},
{0x0000,0x300c,0x0000},
{0x0000,0x1818,0x0000},
{0x0000,0x0420,0x0000},
{0x0000,0x0660,0x0000},
{0x0000,0x03c0,0x0000}, /* Here is where */
{0x0000,0x0180,0x0000}, /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000) /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob7. Only one */
{0x0000,0x0000,0x0000}, /* BitPlane. */
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
PAGE 488
-----------------------------------------------------------------------------
{0x03fc,0x0000,0x3fc0},
{0x0c0f,0x8001,0xe030},
{0x1000,0xe007,0x0008},
{0x2000,0x6003,0x0004},
{0x2000,0x1818,0x0004},
{0x0000,0x0c60,0x0000},
{0x0000,0x0660,0x0000},
{0x0000,0x0240,0x0000},
{0x0000,0x0240,0x0000}, /* Here is where */
{0x0000,0x0180,0x0000}, /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* follows */
},
{
{0x0000,0x0000,0x0000}, /* Data for */
{0x0000,0x0000,0x0000}, /* Bob8. Only one */
{0x0000,0x0000,0x0000}, /*BitPlane. */
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0000,0x0000,0x0000},
{0x0lfe,0x0000,0x7f80},
{0x0301,0xc003,0x80c0},
{0x0400,0x6006,0x0020},
{0x0800,0x1818,0x0010},
{0x0800,0x0c30,0x0010},
{0x1000,0x0420,0x0008},
{0x1000,0x03c0,0x0008},
{0x1000,0x0180,0x0008), /* the data */
{0x0000,0x0180,0x0000}, /* for more */
{0x0000,0x0180,0x0000}, /* BitPlanes */
{0x0000,0x0180,0x0000} /* would follow */
}
};
main()
{
int i,j,k;
char*LeftMouse = (char*)0xBFE001;
/* Left mouse button*/
if ((GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library",0)) == NULL)
{
printf ("No Graphics !!!\n");
exit(0);
}
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",0)) == NULL)
{
printf ("No Intuition !!!\");
goto cleanup2;
}
if((Screen = (struct Screen *)
OpenScreen(&NewScreen)) == NULL)
{
printf ("No Screen !!!\n);
goto cleanup3;
PAGE 489
-----------------------------------------------------------------------------
}
BobBuffer = (UWORD*) AllocMem(MAXCOMPS*20*3*sizeof(UWORD),
MEMF_CLEAR | MEMF_CHIP);
BobMask = (UWORD*) AllocMem(MAXCOMPS*20*3*sizeof(UWORD),
MEMF_CLEAR | MEMF_CHIP);
Image = (UWORD*) AllocMem(MAXBOBS*20*3*sizeof(UWORD),
MEMF_CLEAR | MEMF_CHIP);
if ((Image == 0) | (BobBuffer == 0) | (BobMask == 0))
{
printf ("No Chip Memory !!\n");
goto cleanup4;
}
Help = Image;
for (i=0; i<MAXBOBS;i++)
for (j=0;j<20;j++)
for (k=0;k<3;k++)
{
*Help = BobImage[i][j][k];
Help++;
}
SetRGB4(&Screen->ViewPort,0,2,8,151);
SetRGB4(&Screen->ViewPort,1,0,0,0,);
SetRast (&RP,0);
BltClear (&Start, sizeof(struct VSprite),0);
BltClear (&Ende, sizeof(struct VSprite),0);
BltClear (&GelsInfo, sizeof(struct GelsInfo),0);
BltClear (BobsVSprite,
sizeof struct VSprite)*MAXCOMPS,0);
BltClear (Bobs,
sizeof(struct Bob)*MAXCOMPS,0);
BltClear (AnimComp,
sizeof(struct AnimComp)*MAXCOMPS,0);
BltClear (&Seagull, sizeof(struct AnimOb),0);
/*****************************************************************/
/* A little Copper-Power */
/*****************************************************************/
UCopList = (struct UCopList *)
AllocMem (sizeof(struct UCopList),
MEMF_CHIP | MEMF_CLEAR);
CWAIT (UCopList,150,0);
CMOVE (UCopList,custom.color[0]),0x000f); /* Sea */
CEND (UCopList);
Screen->ViewPort.UCopIns = UCopList;
/* Copper list linked */
RemakeDisplay(); /* and calculate new */
/****************************************************************/
GelsInfo.sprRsrvd = 0xff; /* All Sprites for VSprites*/
PAGE 490
-----------------------------------------------------------------------------
/* Memory for Gelinfo reserved */
GelsInfo.nextLine = (WORD *)AllocMem(sizeof (WORD)*8,
MEMF_PUBLIC | MEMF_CLEAR );
GelsInfo.lastColor = (WORD *)AllocMem(sizeof (LONG)*8,
MEMF_PUBLIC | MEMF_CHIP);
GelsInfo.collHandler = (struct collTable *)
AllocMem(sizeof (struct collTable),
MEMF_PUBLIC | MEMF_CLEAR);
if ((GelsInfo.nextLine == 0) | (GelsInfo.lastColor == 0) |
(GelsInfo.collHandler == 0))
{
printf (" No Memory for GelsInfo !!!\n");
goto cleanup5;
}
GelsInfo.leftmost = 0; /* Boundary Collisions */
GelsInfo.rightmost = 640; /* Border collisions */
GelsInfo.topmost = 0;
GelsInfo.bottommost = 200;
InitGels(&Start, &Ende, &Gelsinfo);
/* GelsInfo initialization */
RP.GelsInfo = &GelsInfo; /* and in RastPort linked */
for (i=0; i<MAXBOBS; i++)
{
Bobs[il.BobVSprite = &BobsVSprite[i];
BobsVSprite[i].VSBob = &Bobs[i];
BobsVSprite[i].Width = 3; /* All Bobs are */
BobsVSprite[i].Height = 20; /* the same size */
BobsVSprite[i].Flags = SAVEBACK;
/* Store background */
/* (in BobBuffer) and */
/* restore it at a time */
BobsVSprite[i].Depth = 1;
/* Only one Plane per Bob */
/* BobsVSprite[i].ImageData */
/* initialised in extra loop*/
BobsVSpriter[i].PlanePick = 1;
/* Only first plane wriiten */
/* to Rast Port */
BobsVSprite[i].PlaneOnOff=0;
/* Remaining planes remain 0 */
BobsVSprite[i].CollMask = BobMask+i*20*3;
BobsVSprite[i].BorderLine = &BobBorderLine[i][0];
/* Memory for CollMask and Borderline */
/* prepared */
Bobs[i].ImageShadow = BobMask+i*20*3;
/* Shadow = CollMask */
Bobs[i].Flags = BOBISCOMP;
/* Bob is part of */
Bobs[i].BobComp=&AnimComp[i];
/* this Animcomps */
PAGE 491
-----------------------------------------------------------------------------
Bobs[i].SaveBuffer = BobBuffer+i*20*3;
/* Memory for SAVEBACK Option */
BobsVSprite[i].Y = 0; /* Position word is */
BobsVSprite[i].X = 0; /* calculated by the */
/* animation system! */
Bobs[i].Before = 0; /* Priorities too!!!!! */
Bobs[i].After = 0;
InitMasks (&BobsVSprite[i]);
/* Initialise CollMask and BorderLine. */
/* (Memory must already be set aside!! */
}
for (i=0; i<MAXBOBS; i++)
BobsVSprite[i].ImageData = Image+i*20*3;
for (i=MAXBOBS-2; i>0; i--)
BobsVSprite[MAXCOMPS[i].ImageData=
Image+i*20*3;
/* Order the Bobs for */
/* Sequence animation */
for (i=0; i<MAXBOBS; i++)
{
AnimComp[i].AnimBob = &Bobs[i] ;
AnimComp[i].PrevComp = 0; /* no further */
AnimComp[i].NextComp = 0; /* AnimComp in */
/* AnimOb */
AnimComp[i].TimeSet = 3; /* 3 mal Animate() */
/* before new sequence */
/* is displayed. */
AnimComp[i].Flags = RINGTRIGGER;
/* Ring-Sequence-Animation */
AnimComp[i].XTrans = 128*64;
AnimComp[i].YTrans = 0;
/* Offset to AM/AnY in Seagull */
/* Note: Fixed decimal ! ! ! */
AnimComp[i].AnimCRoutine = NULL; /* comp; */
/* no AnimComp Routine */
AnimComp[i].HeadOb = &Seagull;
/* HeadOb for AnimComp (for one */
/* routine as intersection mark!)*/
}
/*Sequence: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
/*Bobs/AnilComp: 1 2 3 4 5 6 7 8 9 6 5 4 3 2 */
for (i=MAXBOBS-2; i>0; i--)
{
AnimComp[14-i].AnimBob = &Bobs[i];
AnimComp[14-i].PrevComp = 0;
AnimComp[14-i].NextComp = 0;
AnimComp[14-i].TimeSet = 3;
AnimComp[14-i].Flags = RINGTRIGGER;
AnimComp[14-i].XTrans = 128*64;
AnimComp[14-i].YTrans = 0;
AnimComp[14-i].AnimCRoutine = NULL; /* Comp; */
Bobs[14-i].BobComp = &AnimComp[14-i];
AnimComp[l4-i].HeadOb = &Seagull;
} /* see above */
for (i=1; i<MAXCOMPS-1; i++)
{
PAGE 492
-----------------------------------------------------------------------------
AnimComp[i].NextSeq = &AminComp[i+1];
AnimComp[i].PrevSeq = &AnimComp[i-1];
/8 intitialize 'Ring' for Ring/Sequence */
/* Animation (PrevComp and NextComp remain */
/* here without action and in this case */
/* are not initialised, but set to 0 */
}
AnimComp[0].NextSeq = &AnimComp[1]; /* Close ' Ring ' */
AnimComp[0].PrevSeq = &AnimComp[13];
AnimComp[MAXCOMPS-1].NextSeq = &AnimComp[0];
AnimComp[MAXCOMPS-1].PreqSeq = &AnimComp[12];
Seagull.HeadComp = &AnimComp[0]; /* Animobs first */
/* AnimComp */
Seagull.RingXTrans = 2*64; /* X/Y Translation */
Seagull.RingYTrans = 1*64; /* of seagull */
Seagull.AnX = 0; /* start position */
Seagull.AnY = 0; /* of XTrans */
Seagull.XAccel = 0x0000; /* has no movement */
Seagull.YAceel = 0x0000;
Seagull.XVel = 0x0000; /* no movement speed */
Seagull.YVel = 0x0000;
Seagull.AnimORoutine = MoveSeagull;
/* User control routine */
AddAnimOb(&Seagull,&HeadOb,&RP);
/* Animob in list */
while (&LeftMouse & 0x40) == 0x40)
{
Animate(&HeadOb,&RP); /* Sort */
SortGList(&RP) ; /* Animation */
WaitTOF(); /* to prevent blinking the bobs! */
DrawGList(&RP, &Screen->ViewPort); /* Draw */
}
/* GelsInfo's memory freed */
cleanup5:
if (GelsInfo.nextLine != 0)
FreeMem(GelsInfo.nextLine, sizeof(WORD)*8);
if (GelsInfo.lastColor != 0)
FreeMem (GelsInfo.lastColor, sizeof(LONG)*8);
if (GelsInfo.collHandler != 0)
FreeMem (GelsInfo.collHandler,
sizeof(struct collTable));
cleanup4:
if (Image != 0)
FreeMem(Image,MAXBOBS*20*3*sizeof(UWORD));
if (BobBuffer != 0)
FreeMem(BobBuffer,MAXCOMPS*20*3*sizeof(UWORD));
if (BobMask != 0)
FreeMem(BobMask, MAXCOMPS*20*3*sizeof(UWORD));
cleanup3: CloseScreen(Screen);
cleanup2: CloseLibrary(IntuitionBase);
cleanup1: CloseLibrary(GfxBase);
}
/*****************************************************************/
/* This function is called each time by Animate() */
/*---------------------------------------------------------------*/
PAGE 493
-----------------------------------------------------------------------------
/* Input parameter : AnimOb-Structure, animated with */
/* Animate(). These parameters are */
/* passed by Animate() */
/*--------------------------------------------------------------*/
/* Returnvalue : none */
/****************************************************************/
WORD MoveSeagull (Object)
struct AnimOb *Object;
{
if ((Object->AnX < (-128*64)) || /* 1st user object */
(Object->AnX > ((512-48)*64))) /* corner? */
Object->RingXTrans *= -1;
if ((Object->AnY < (0)) ||
(Object->AnY > (120*64)))
Object->RingYTrans *= -1;
}
/*****************************************************************/
/* This function is called each time by Animate() */
/*---------------------------------------------------------------*/
/* Input parameter : AnimOb-Structure, animated with */
/* Animate(). These parameters are */
/* passed by Animate() */
/*---------------------------------------------------------------*/
/* Returnvalue : none */
/*****************************************************************/
/* WORD Comp(Component)
struct AnimComp *Component;
{
return(0);
} */
PAGE 494
-----------------------------------------------------------------------------
19. Copper Programming in C
As you already know from the previous chapters, the Copper is a coprocessor
of the Amiga. It is responsible for the visible display, which means that
it determines what appears at a specific position of the electronic beam.
The Copper also helps display sprites and vsprites However, a more
important feature of the Copper is that it can be programmed by the user.
Simply insert a pointer to the user Copper list (struct UCopLiSt
*UserCopperList), which uses the Copper instructions to program the Copper.
However, before you can use this you must assign enough memory for
your user Copper list: UserCopperList = (struct UCopList *) AllocMem(sizeof
(struct UCopIns), MEMF_PUBLIC | MEMF_CLEAR).
You must clear the memory for this structure. Do this either directly
with AllocMem through the MEMF-CLEAR option, or afterwards with BltClear.
This allows the entry of new Copper instructions and then tells MakeVPort
that the user Copper list is still empty.
Now that we have explained all the preliminary steps, we can proceed to the
Copper language. It is very simple and concise of only three instructions,
CMOVE, CWAIT and CEND. These three instructions are all that is needed
to program pull down Intuition screens.
The CMOVE instruction enables you to write a value into a specific hardware
register (see Appendix C). Both the hardware register and the value are
specified by you with the Custom structure, which allows you to access the
hardware registers. To create this structure first use extern struct Custom
custom and then use custom.<Registername> to access the individual
hardware registers.
Now give the CMOVE instruction as a parameter and, as you may have assumed,
the absolute address of the desired hardware register. The Copper only
works with offsets of the registers from $DF000 and CMOVE calculates the
absolute address for you.
You must provide a pointer to this structure beforehand so that the CMOVE
instruction also knows where to find the user Copper list.
PAGE 495
-----------------------------------------------------------------------------
Now you must supply the 16 bit value (Word) that will be wrilten into
the desired hardware register.
A complete call with the CMOVE instruction would look like this:
CMOVE (UserCopperList, Custom.<RegisterName>, Value);
There is a small restriction you should remember when using the CMOVE
instruction. Usually you can write to any hardware register numbered higher
than $20 (dskpt) without any limitations. However, you cannot under any
circumstances, address register numbers smaller than $10 (adkconr) through
the Copper. It is possible to write only to registers that fall between $10
and $20 after you have set the Copper DangerBit in register (copcon)
(number $2E).
When discussing sprite collision detection, we explained how you
access the hardware registers with help from the 68000. Review that
section if necessary.
Another Copper instruction is CWAIT. This instruction enables you to
wait for the electronic scanning beam to reach a specific position. The
user Copper list doesn't perform any other instructions until the
scanning beam reaches the specified position (The Copper program
won't have any effect on your C program). For example, you could wait
for any desired position and change the contents of one of the color
registers. You could also use this technique to display one of your
sprites beginning in the middle of the screen.
When you use the CWAIT instruction you must tell the user Copper list
where your instructions will be located. You must also provide the X and
Y position that the electronic beam should wait for. The order of the X and
Y coordinates is very important. First specify the Y coordinate and then
the X coordinate. Pay close attention to the order of these coordinates
because using them out of sequence can be very frustrating. Your Copper
program will not function properly if the Y coordinate isn't first.
CWAIT (&UserCopperList,Y,X) lets you wait for a specific electronic beam
position. Remember that the Y position must be smaller than 263 and the X
position must be smaller than 223. Also, you must set the Y position
relative to the top of your ViewPort and the X position relative to the
normal scanning position. This means that for the X position you have to
consider Overscan. The electronic beam actually covers a much larger area
than is visible on the screen. A good value to use for positioning the
electronic beam at The left ViewPort border is X=60 plus or minus 2 or
View.DxOffset/2 plus or minus one.
PAGE 496
-----------------------------------------------------------------------------
So that the Copper program ends properly, we use the CEND instruction.
The only parameter needed is the user Copper list that will be ending.
CEND (&UserCopperList) waits for the electronic beam to reach row position
10000 and column position 256. Since this position is never reached,
the user Copper list is no longer used.
When the electronic beam reaches the bottom of the screen, it will start at
the top row again (Top Of Frame). All Copper lists for the ViewPorts and the
user Copper Iist are run again.
The Copper can perform raster row interrupts similar to the ones from the
Commodore 64. However, unlike the Commodore 64, the Copper can also change
a color in the middle of a raster row. Remember that each CMOVE instruction
requires a maximum resolution of 8 pixels. This means that with a normal
resolution, a CMOVE instruction can only by performed every 8 pixels.
Therefore, between two consecutive CMOVE instructions there must be an 8
pixel gap.
The CwAIT instruction allows you to wait for electronic beam positions that
are spaced only 4 pixels apart. However, When a CMOVE instruction follows a
CWAIT instruction, an 8 pixel gap is still required.
After using the above instruction to create your user Copper list, you must
provide this information to the ViewPort that will use the list. To do this
use ViewPort.UCopIns = UserCopperList. When using Intuition screens, use the
following form, Screen>ViewPort.UCopIns = &UserCopperList.
Now open your own screens by calling MakeVPort and MrgCop.
Intuition screens are handled differently. OpenScreen generates the Copper
list for the screen. Afterwards, use RemakeDisplay to ensure that the new
user Copper list is added to the global View Copper list.
FreeVPortCprList and CloseScreen release the dynamically reserved memory for
the UCopList, a two word pointer that contains your instructions. No
additional instructions, such as FreeMem need to be executed. Make sure you
declare your user Copper list as a pointer and reserve the required memory
for the UCopList structure in your program. FreeVPortCprList and CloseScreen
free the memory for not only the instruction list, but (also for the
UCopList Structure.
When you declare the UCopList as a normal structure, the memory that it uses
is released twice. It is released first by FreeVportCopLists and then by
your program, which ends by
PAGE 497
-----------------------------------------------------------------------------
returning all used memory areas to the system. This double release of one
memory area causes the familiar Guru Meditations.
To avoid this, always declare your UCopList as a pointer that is later used
to assign your memory.
Finally, another small tip: To change your Copper list in your program you
must clear your reserved UCopList structure (BltClear is best) and build a
new list.
/***********************************************************************/
/* Copper. c */
/* */
/* This Program demonstrates how you can access the */
/* AMIGA Hardware-Registers with Help from the Copper. */
/* Compiled with: Aztec C 3.6a */
/* cc +L -s Copper.c */
/* ln Copper.0 -lc32 */
/* (c) Bruno Jennrich */
/***********************************************************************/
#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/memory.h"
#include "graphics/gfx.h"
#include "graphics/gfxmacros.h"
#include "graphics/gfxbase.h"
#include "graphics/text.h"
#include "graphics/regions.h"
#include "graphics/clip.h"
#include "graphics/view.h"
#include "graphics/copper.h"
#include "graphics/gels.h"
#include "hardware/blit.h"
#include "hardware/custom.h"
#define WIDTH 320
#define HEIGHT 200
/* PAL 256 HERE */
#define MODES 0
struct View View;
struct ViewPort ViewPort;
struct RasInfo RasInfo;
struct BitMap BitMap;
struct RastPort RastPort;
struct GfxBase *GfxBase;
struct View *oldview;
struct UCopList *UserCopperList; /* our Copper List */
extern struct ColorMap *GetColorMap();
/* extern struct Custom custom; in custom.h */
/* For Access to the */
/* Hardware-Register */
PAGE 498
-----------------------------------------------------------------------------
UWORD Colors[16l = {
0x000,0x0bbd,0x0f0,0xf00,
0x123,0x435,0x678,0x009,
0x123,0x435,0x678,0x009,
0x123,0x435,0x678,0x009
};
/* Own ColorMap. */
/* Color reg. 1 is */
/* changed by the */
/* Copper */
char *LeftMouse = (char *)0xbfe001;
char *Texts[15] = {"COPPER-Programming with the AMIGA",
"";
"The SPECIAL-EFFECTS Processor in Action";
"";
"";
"Colors underneath the Text";
"(a standard feature of Games)",
"and how it is done.";
"";
"";
"";
"This Effect is especially spectacular";
"when used with Moving BOBS !";
"";
"(MOUSE BUTTON)};
/**************************************************************/
/* Here we go ! */
/**************************************************************/
main()
{
long i,Len;
if ((GfxBase = (struct GfxBase *)
Open Library ("graphics.library",0)) == NULL )
{
printf (" No Graphics !!!\n");
Exit(10);
}
oldview = GfxBase->ActiView; /* Build a Screen as */
InitView(&View); /* usual */
InitVPort(&ViewPort);
View.Modes = MODES;
View.ViewPort = &ViewPort;
ViewPort.DWidth = WIDTH;
ViewPort.DHeight = HEIGHT;
ViewPort.Modes = MODES;
RasInfo.RyOffset = 0;
RasInfo.RxOffset = 0;
RasInfo.Next = 0;
ViewPort.RasInfo = &RasInfo;
ViewPort.ColorMap = GetColorMap(l6);
PAGE 499
-----------------------------------------------------------------------------
LoadRGB4 (GViewPort, &Colors, 16) ;
InitBitMap(@BitMap, 4, WIDTH, HEIGHT);
for (i=0; i<4; i++)
Bitmap.Planes[i].(PLANEPTR)
AllocRasteR(WIDTH,HEIGHT);
if (BitMap.Planes[i] == NULL)
{
printf("No BitMap - Space !!!\n");
Exit(0);
}
InitRastPort(&RastPort);
RastPort.BitMap = &BitMap;
RasInfo.BitMap = &BitMap;
SetRast (&RastPort,0);
SetAPen (&RastPort,1);
for (i=0;i<17;i++)
{
Len = WIDTH/2-
TextLength(&RastPort,Texts[i], strlen(Texts[i]))/2;
Move (&RastPort, Len,i*9+63+RastPort.TxBaseline);
/* Y-Coordinate should be divisible by 9 ! */
Text (&RastPort,Texts[i],strlen(Texts[i]));
MakeVPort(&View,@ViewPort); /* Display ViewPort. */
MrgCop(&View); /* Makes the difference */
LoadView(&View); /* visible. */
UserCopperList = (struct UCopList *)
AllocMem(sizeof (struct UCopList),MEMF_CHIP);
/* Reserve the required Memory */
/* for the UCopList-Structure */
BltClear(UserCopperList, sizeof(struct UCopList),0);
/* Clear UCopList-Structure */
for (i=0; i<256; i+=9)
{
CWAIT (UserCopperList,i,view.DxOffset/2);
CMOVE (UserCopperList,custom.color[1],0x0fff);
/* white */
CWAIT (UserCopperList,i+3,view.DxOffset/2);
CMOVE (UserCopperList,custom.color[1],0x0bbd);
/* light purple */
CWAIT (UserCopperList,i+5,View.DxOffset/2);
CMOVE (UserCopperList,custom.color[1],0x088b);
/* purple */
CWAIT (UserCopperList,i+7,View.DxOffset/2);
CMOVE (UserCopperList,custom.color[1],0x0558);
/* dark purple */
}
PAGE 500
-----------------------------------------------------------------------------
CEND (UserCopperList ); /* End UCopList */
Delay (100); /* Wait 2 Seconds */
ViewPort.UCopIns = UserCopperList;
/* Link ViewPort and UCopList */
MakeVPort (&View,&ViewPort);
/* Calculate ViewPort Copper-List */
/* with a Intuition Screen using */
/* RethinkDisplay() */
MrgCop(&View);
LoadView(&View);
while ((*LeftMouse @ 0x40) == 0x40);
/* Wait for Mouseclick */
LoadView (oldview);
for (i=0; i<4; i++)
FreeRaster (BitMap.Planes[i],WIDTH, HEIGHT);
FreeColorMap(ViewPort.ColorMap);
FreeVPortCopLists(&ViewPort);
/* UCopList automatically released */
FreeCprList(View.LOFCprList);
FreeCprList(View.SHFCprList);
/* View-Copper List FREE */
CloseLibrary(GfxBase);
return (0);
}
PAGE 501
--------------------------------------------------------------------------
APPENDIX A: STRUCTURE AND INCLUDE FILES.
This appendix contains a listing of all symbolic constants (#define xyz
numerical value) and the include file in which these constants are
located. Also listed are all used structures (struct) and all used C
macros (#define xyz()). At the end of this appendix we explain the structure
functions and provide more details for the most important structure
details.
Declaration Include File.
------------------------------ ----------------------------------
struct AnimOb "graphics/gels.h"
struct AnimComp "graphics/gels.h"
struct AreaInfo "graphics/rastport.h"
#define AREAOUTLINE "graphics/rastport.h"
struct AvailFonts "libraries/diskfont.h"
struct AvailFontsHeader "libraries/diskfont.h"
struct BitMap "graphics/gfx.h"
struct Bob "graphics/gels.h"
#define BNDRYOFF() "graphics/gfxmacros.h"
#define BOBISCOMP "graphics/gels.h"
#define BOBSAWAY "graphics/gels.h"
#define BOTTOMHIT "graphics/collide.h"
#define CEND0 "graphics/gfxmacros.h"
#define CMOVE0 "graphics/gfxmacros.h"
struct ColorMap "graphics/view.h"
#define COMPLEMENT "graphics/rastport.h"
struct Custom "hardware/custom.h"
#define CUSTOMBITMAP "intuition/intuition.h"
#define CUSTOMSCREEN "intuition/intuition.h"
#define CWAIT0 "graphics/gfxmacros.h"
struct DBuffPacket "graphics/gels.h"
#define DUALPF "graphics/view.h"
#define EXTRA_HALFBRITE "graphics/view.h"
struct GelsInfo "graphics/gels.h"
#define GELGONE "graphics/gels.h"
struct GfxBase "graphics/gfxbase.h"
#define HAM "graphics/view.h"
#define HIRES "graphics/view.h"
#define INVERSVID "graphics/rastport.h"
struct IntuitionBase "intuition/intuitionbase.h"
struct IntuiMessage "intuition/intuition.h"
PAGE 503
---------------------------------------------------------------------------
#define JAM1 "intuition/intuition.h"
#define JAM2 "intuition/intuition.h"
#define LACE "graphics/view.h"
#define LEFTHIT "graphics/collide.h"
struct NewScreen "intuition/intuition.h"
struct NewWindow "intuition/intuition.h"
#define MEMF_CHIP "exec/memory.h"
#define MEMF_PUBLIC "exec/memory.h"
struct Menu "intuition/intuition.h"
struct MenuItem "intuition/intuition.h"
#define OVERLAY "graphics/gels.h"
#define PFBA "graphics/view.h"
#define RASSIZE() "graphics/gfx.h"
struct RasInfo "graphics/view.h"
struct Rastport "graphics/viewport.h"
#define RemBob() "graphics/gels.h"
#define RINGTRIGGER "graphics/gels.h"
#define RIGHTHIT "graphics/collide.h"
struct Screen "intuition/intuition.h"
#define SAVEBACK "graphics/gels.h"
#define SAVEBOB "graphics/gels.h"
#define SUSERFLAGS "graphics/gels.h"
#define SELECTDOWN "intuition/intuition.h"
#define SELECTUP "intuition/intuition.h"
#define SetOPen() "graphics/gfxmacros.h"
#define SetDrPt() "graphics/gfxmacros.h"
#define SetWrMsk() "graphics/gfxmacros.h"
#define SetAfPt() "graphics/gfxmacros.h"
struct SimpleSprite "graphics/sprite.h"
#define SPRITE_ATTACHED "graphics/sprite.h"
struct TextAttr "graphics/text.h"
struct TextFont "graphics/text.h"
struct TmpRas "graphics/rastport.h"
#define TOPHIT "graphics/collide.h"
struct UCopList "graphics/copper.h"
typedef ULONG "exec/types.h"
typedef UWORD "exec/types.h"
struct View "graphics/view.h"
struct ViewPort "graphics/view.h"
#define VP_HIDE "graphics/view.h"
struct VSprite "graphics/gels.h"
#define WBENCHSCREEN "intuition/intuition.h"
struct Window "intuition/intuition.h"
PAGE 504
-----------------------------------------------------------------------------
struct AnimComp
{
WORD Flags;
THese variables enable you to determine the type of
animation to use. When you set the RINGTRIGGER flag it
means you have set up a ring of ANIMCOMPS. You link the
ring through the AnimComp.NextSeq and AnimComp.PrevSeq.
Animate can automatically display different sequences
(like a flying bird) by using the AnimComp ring.
Unless you set RINGTRIGGER, animation is not possible.
WORD Timer;
This variable is loaded with the timeset variable and
decremented (if set to decrement to zero) with each
Animate() call. Whenver Timer reaches zero, depending on
your setup (RINGTRIGGER), a new sequence is displayed.
WORD TimeSet;
The value contained here is written into Time and
decremented there by every Animate() call. TimeSet
determines how long an animnation sequence is active. The
next sequence starts after a certain number of Animate()
calls.
struct AnimComp *NextComp;
struct AnimComp *PrevComp;
These two variables allow you to link many animation
objects (AnimOb) together for display by Animate(). For
example, the AnimObs for the arms, legs and head of a man
can be linked together. Please remember that NextComp and
PrevComp should not be used to animate a sequence for
moving an arm while walking. You must use NextSeq and
PrevSeq for these type of animations.
struct AnimComp *NextSeq;
struct AnimComp *PrevSeq;
When you want to repeatedly change an animation component
define different display (sequences) of an object (for
example, an arm). Then use the above two pointers to tell
Animate() that you want the arm displayed in different
positions. You program the various arm movement positions
and then they are displayed.
WORD (*AnimCRoutine)();
You either set this pointer to zero or point it to a
function you have defined. Each call of Animate() that
displays your components also calls this function. Your
routine is passed to the current AnimComp structure.
PAGE 505
-----------------------------------------------------------------------------
WORD YTrans, XTrans;
These two pointers contain the position of the AnimComps
relative to the AnimObs defined earlier. (Please remember
to use the fixed decimal arithmetic for these variables).
struct AnimOb *HeadOb;
This pointer points to the previously defined AnimOb of
which the AnimComp is a part.
struct Bob *AnimBob;
Naturally Animate() must also know what should be
displayed. For this purpose the AnimComp structure contains
a pointer to the bob this is associated with the AnimComp.
(Please make sure that the bob also has its own VSprite
structure).
}
The AnimComp, or the animation components, determine the connection between
bob and animation object (AnimOb). This is especially important with
Sequence Animation (RINGTRIGGER) because it connect the individual
components together in a ring and sets the amount of time each sequence is
active.
-------------------------------------------------------
struct AnimOb
{
struct AnimOb *NextOb *PrevOb;
The variables mkae it possible for you to link many
animation object together. The linked objects are then
animated with Animate() and then with SortGList().
DrawGList() etc are all displayed on the screen (for
example several men).
LONG Check;
This variable contains a count of the calls to Animate()
that have been used for an AnimOb.
WORD AnOldY AnOldX;
These variables contain the old position of an animation
object. We save the old position because the current
position (AnX, AnY) does not change until timer reaches
zero for the current AnimComp. The user can change the
position between movements which causes some components to
be displayed in the wrong positions. For this reason, we
store the old position. After numerous Animate() calls the
actual position is calculated using the old position and
the following variables.
WORD AnX, AnY;
These variables contain the actual positions of the AnimObs.
They do not contain values for pixel and row positions
within a RastPort. Depending on the speed and motion
variables, they contain values in steps of 64 for pixels
and lines.
PAGE 506
-----------------------------------------------------------------------------
This means you must use AnX = Width/2 * 64 and
AnY = Height/2 * 64 to move AnimOb to the middle of the
screen. Again we have a problem using horizontal values
plus or minus 32768 versus positions over 512 (=32768/64).
The following trick can help: The variable XTrans (and
YTrans) in the AnimComp structure set the position of an
AnimComp relative to the previously defined AnimOb. When
you simply initialise XTrans with a value of 128*64 you
can move an object around the entire screen (512+128 = 640)
even in hires mode. For horizontal values less than 128
you simply use negative values with AnX.
WORD YVel, XVel;
The speed of an AnimOb is contained in these two variables.
The values in YVel and XVEL and added to AnY and AnX
after every Animate() call. Because Animate() is normally
called many timed per second it is possible for your object
to move erratically on the screen. To prevent this,
velocity and acceleration are set using step values of 64
for every Animate() (this is the reason for the unusual
method used for the values in AnX and AnY). This means that
with a value of one in XVel, 64 Animate calls have to
occur before the object moves one pixel.
WORD YAccel, XAccel;
These variables determine the motion of your AnimOb. These
variables must also be set in steps of 64. The values in
XAccel and YAccel are added to XVel and YVel.
WORD RingYTrans, RingXTrans;
These variables set the speed of the AnimOb. They are added
directly to AnX and AnY. Motion isn't a factor here.
WORD (*AnimORoutine) ();
The routine whose addres is specified here is called once
by every Animate() call. This routine is passed to the
current AnimOb stucture so that the actual position of the
current AnimOb is controlled and the proper reaction is
received.
struct AnimComp *HeadComp;
This pointer points to the first animation component of an
AnimOb.
AUserStuff AUserExt;
Link your own structures (see VSPRite, VUserStuff) here.
}
The AnimOb structure contains a complete animation object. You use
AddAnimOb() to make this structure available to the system and then use
Animate() for animation.
PAGE 507
-----------------------------------------------------------------------------
struct AvailFonts
{
OWORD af_Type;
These variables determine whether the TextAttr structure
specified below uses a font in memory (AFF_MEMORY) or a
diskfont in the "SYS:fonts" directory (AFF_DISK). This is
important for determining whether you should use OpenFont()
or OpenDiskFont() to open a font.
struct TextAttr af_Attr;
This is the TextAttr structure returned by AvailFonts().
}
This structure is only used by the routine AvailFonts() (and by you, of
course). It is written after the AvailFontsHeader is located in a memory
area where it is available for use by AvailFonts().
--------------------------------------------
struct AreaInfo
This structure is required for the Area function. It is initialised with
InitArea and used for the coordinates of a polygon corner points.
--------------------------------------------
struct AvailFontsHeader
This structure can only be created by using the routine AvailFonts() and
contains only one variable: afh_NumEntries. This variable contains the
count of the AvailFonts structures written after the AvailFontsHeader in
the memory area specified by the AvailFonts() routine.
--------------------------------------------
struct BitMap
{
UWORD BytePerRow;
This variable contains the byte count required for one
bitmap row (BytesPerRow = Width/8).
UWORD Rows;
The line count for a bitmap (height) is contained in this
variable.
UWORD Flags;
This variable is only used by the system.
PAGE 508
-----------------------------------------------------------------------------
UBYTE Depth;
The number of bitplanes in a bitmap are contained in this
variable. Please remember that the depth determines the
number of available colours (colors = 2^NumBitPlanes).
UWORD pad;
This is one full WORD so the following pointer begins with
a LONG WORD address.
PLANEPTR Planes[8];
These eight pointers contain the addresses of the
individual bitplanes for the bitmap. Although now you can
only use six of the eight pointers you can see that there
are possibilities for future expansions.
}
The BitMap structure contains the addresses for the individual memory areas
where graphics are stored. In addition, information for the height, width
and depth of the bitmap are contained here.
--------------------------------------------
struct Bob
{
WORD Flags;
Through these variables the user can determine how the bob
is handled by the system. The SAVEBOB flag tells the system
that once the bob is drawn it won't be cleared from the
RastPort (brush function). You use BOBISCOMP to make the
bob part of an animation component. Make sure that you
also point the pointer BobComp to the corresponding
AnimComp structure.
Not only the user can set the bob flags, the system can
also set the so-called status flags. These flags provide
information about the status of a bob. For example, the
flag BOBNIX tells us that the bob has disappeared from the
RastPort, the background has been restored, and the BOB
was removed from the GEL list.
WORD *SaveBuffer;
This pointer points to a memory area, reserved by you,
where the background will be stored when a bob is drawn.
Because bobs are normally written directly into the bitmap,
the background where the bob appears is destroyed. When you
set the SAVEBACK flag in the vsprite structure the background
is saved to the memory area. This area must be at least as
wide an high as the bob being drawn. You must also make sure
that for every bitplane of the RastPort being written to
(see PlanePick and planeOnOff in the VPsrite structure) a
buffer in chip memory is reserved. The background is
saved into these memory buffers.
PAGE 509
-----------------------------------------------------------------------------
WORD *ImageShadow;
As you may already know, you define a bob bitplane by
bitplane and use PlanePick and PlaneOnOff to determine in
which plane the bob is drawn. ImageShadow points to a
memory buffer that is large enough to store one bitplane
of your bob. All the set pixels in the individual bitplanes
for your bob are stored in ImageShadow. In other words, all
the Bob-Planes are ORed and stored in ImageShadow (chip
memory).
struct Bob *Before;
struct Bob *After;
These two pointers determine the order the bobs are drawn.
They can be used to make the GEL routines use your bobs in a
specific order. However, since this function removes
pointers, you must do this after AddBob().
struct VSprite *BobVSprite;
Each bob requires a vsprite structure because the bob
structure doesn't contain any variables for positioning.
In addition, the GEL list is made up of only vsprite
structures and the bob must be in this list somehow. To
make this work, this pointer points to the vsprite structure
for the bob (every bob has its own).
struct AnimComp *BobComp;
This pointer points to the AnimComp structure to which the
bob belongs. You set this pointer only after setting the
flag BOBISCOMP.
struct DBuffPacket *DBuffer;
When you want to use bobs with a double buffered bitmap,
which saves both bitmaps for the background, you must
initialise this pointer to DoubleBufferPacket. This makes
it possible for the GEL software to easily display the
bobs in both bitmaps, without any extra work (chip mem).
BUserStuff BUserExt;
Here you, the user, can add your own extensions to the bob
structure. Simply used #define BUserStuff to define the
type of extension in your program. This extension can then
be accessed either by the AnimCRoutines, AnimORoutines or
a collision routine. When you don't define BUserStuff, it is
automatically defined as a SHORT variable.
The bob structure defines the bob (blitter object). Bobs can be as large as
you want and can contain as many colours as the RastPort in which they are
used.
PAGE 510
-----------------------------------------------------------------------------
struct ColorMap
You use this structure to set the colours for a ViewPort. To change them
afterwards use LoadRGB4(), getRGB4() and SetRGB4().
--------------------------------------------
struct Custom
This structure provides a picture of the hardware registers which helps
you effictively access them with C. The Appendix for the hardware registers
describes all the symbol registers for this structure and how to use them
(chip memory).
--------------------------------------------
struct DBuffPacket
This structure was designed for using bobs in double buffered bitmaps.
The backgrounds from both bitmaps, which are selected by you, are saved
here when the bob is drawn over them. When you set the SAVEBACK flag in
the vsprite structure the background is saved from only one of four
bitmaps. By installing a DBuffPacket(Bob.DBuffer = &DBuffPacket) for every
bob, you can also save the background of the second bitmap. However, a
DBuffPacket cannot be generated for only one bob in a GEL list. Either
all or none of the bobs in the GEL list have a DBuffPacket.
You must also provide the DBuffPacket structure and the address of an
additional memory area in chip memory (DBuffPacket.BufBuffer = &Memory).
This area must be the same size as the Bob.SaveBuffer. The other
variables for DBuffPackets are handled by the GEL software.
--------------------------------------------
struct GfxBase
GfxBase is your pointer to the graphic function library. You initialise
this library with GfxBase = OpenLibrary("graphics.library",VERSION_NUMBER).
Now you have access to all the graphic functions that the Amiga has
available.
Also, GfxBase contains a pointer to the currently active View. When you
use a program that creates its own View, without intuition, you should
save the current View. By using OldView = GfxBase->ActiView you can
save this pointer, return the intuition View and, thereby, thw workbench
screen.
Another GfxBase structure variable, GfxBase->SpriteReserved provides
information on the hardware sprites that are currently available for use.
PAGE 511
-----------------------------------------------------------------------------
There are a few more pointer in GfxBase such as the SystemFont list etc..
that are exclusively for system use. These pointer can also be affected
by the Graphic functions.
--------------------------------------------
struct GelsInfo
{
BYTE sprRsrvd;
This variable provides information about the sprites
available to the vsprite generator. When your program does
not require the hardware sprites simply set all the bits
in sprRsrvd. This tells the Amiga to use all the hardware
sprites as vsprites. If you want to use both hardware
sprites and vsprites, you must ensure that your hardware
sprites are not used as vsprites. To accomplish this, clear
the corresponding bit in SprRsrvd (bit 0 for sprite 0 and
bit 1 for sprite 1 etc..).
UBYTE Flags;
These variables are used only by the system.
struct VSprite *gelHead, *GelTail;
The GELs (vsprites and bobs) are organised in a GEL list.
These two pointers point to the beginning and end of this
list and are initialised with InitGels().
WORD *nextLine;
This pointer points to a memory area that is eight words
long. It contains information on the highest vertical
positions at which a hardware sprite can be displayed
by using the vsprite software.
WORD **lastColor;
This eight pointer array helps the copper. It stores the
address of the last color definition that was saved for the
hardware sprites. This address is compared to the colour
table address for the new sprite that will be displayed.
If they are the same, a color change is not performed by the
Copper because these colours have already been displayed.
When all eight pointers point to the same vsprite color
table you can display up to eight vsprites in one raster
row instead of only four.
struct collTable *collHandler;
This is where you store the various addresses for collision
routines using SetCollision(). Whether or not these are
called depends on which GELs collide with which collision
masks (MeMask and HitMask).
short leftmost, rightmost, topmost, bottommost;
These four variables are used to set the rectangle
boundaries within which your GELs are confined without
having a Border_Collision. When you GEL exceeds these
boundaries, collision routine zero is called. In order for
this to function you must set bit zero in the GELs BitMask.
PAGE 512
-----------------------------------------------------------------------------
APTR firstBlissObj.lastBlissObj;
These two pointers are only used by the operating system.
}
The GElsInfo structure contains very important variables and pointers for
the GELs (graphic elements). It must be initialised with InitGels() before
the GEL routines (AddBob(), AddVsprite(), Animate(), AddAnimOb()) can be
used. This structure must be passed to the initialised RastPort (RastPort.
GElsInfo = &GelsInfo).
--------------------------------------------
struct IntuiMessage
This structure allows you to intercept and check messages received by
Intuition, such as those from a window. With their help you can determine
whether or not a menu item has been selected, the mouse has moved or a
mouse button has been pressed.
--------------------------------------------
struct IntuitionBase
Just as any library, the intuition library also has a BasePointer.
This base pointer is used in the same way as the starting address for
accessing the library functions.
--------------------------------------------
struct NewWindow
{
SHORT LeftEdge, TopEdge;
SHORT Width, Height;
These four variables determine the position of a window.
(LeftEdge (X coordinate), TopEdge (Y coordinate)), width
and height.
UBYTE DetailPen, BlockPen;
These two variables are used to set the color for your
BlockPen and the Title. The values you use here are the
same ones used for SetAPen() (the number of the colour
register).
ULONG IDCMPFlags;
The IDCMP flags (Intuition Direct Communication Message
Ports) determine the type of communication between the user
and Intuition. You can decide what messages are sent, by
Intuition to your program. You may also want to receive
messages for a mouseclick (MOUSEBUTTON) or a key press
(RAWKEY / VANILLAKEY). Unfortunately, we do not have
enough room here to provide a complete listing of all the
IDCMPs.
PAGE 513
-----------------------------------------------------------------------------
ULONG Flags;
By using these flags it is possible to describe a window
in more detail. For example, you can set BORDERLESS so
the window has no border. With ACTIVATE, a window can be
active as soon as you open it and will immediately become
the input/output window. Again, a complete list of all the
possibilities is not possible here.
struct Gadget *FirstGadget;
This pointer points to the first gadget you have created.
Gadgets are similar to the small boxes seen in the upper
right corner of system windows, which place the window in
the background when they are clicked.
struct Image *CheckMark;
This pointer points to the Image structure used for the
checkmark, which is used to show static menu items. By
entering a zero here you can use the default checkmark.
UBYTE *Title;
When you want to use several windows it is easier to give
each one a name or title. This name is displayed in the top
row of the window. Title is the pointer to the first
character of your title string (for example, the system
window is named AmigaDOS).
struct Screen *Screen;
In order for a window to exist, it needs a screen. A window
must be displayed at some time. This pointer points to an
opened screen where the window is later displayed.
struct BitMap *BitMap;
When you have set the SUPER_BITMAP flag in the flags
variables, this pointer must point to the bitmap you have
created. It is possible to create a bitmap with 1024*1024
pixels and display part of it as large as the window on
your screen.
SHORT MinWidth, MinHeight;
SHORT MaxWidth, MaxHeight;
Once you have set the WINDOWSIZING flag in the flags
variables (and also set SIZEBRIGHT (Size Border Right) or
SIZEBOTTOM (Size Border Bottom) the window sizing gadget
will appear. This gadget, located in the bottom right
corner of your window, allows you to change the size of
your window. You can set the sizing limits by using the
variables MinHeight, MinWidth, MaxHeight and MaxWidth.
PAGE 514
-----------------------------------------------------------------------------
USHORT Type;
This variable lets you determine whether or not this window
will appear in the Workbench area (WBENCHSCREEN). Here you
must set the screen structure pointer to zero otherwise the
window will appear in its own screen (CUSTOMSCREEN). You
must also provide the NewWindow structure with an address
for the screen where the window should appear.
}
These structures let you describe a window. After setting all the pointers
and variables, call Window = OpenWindow (&NewWindow). As an example, you
can now use your window for graphic output.
--------------------------------------------
struct NewScreen
{
SHORT LeftEdge, TopEdge, Width, Height, Depth;
These variables allow you to set the position, size and
depth (number of bitplanes) for your screen. While doing
this, you must also ensure that your window cannot be
moved horizontally (in the X direction). Otherwise, values
for LeftEdge that are not equal to zero will have the same
effect as if they were equal to zero.
UBYTE DetailPen, BlockPen;
The colour for text (DetailPen) and title (BlockPen) for
the top screen row are also set here in the same way as
windows.
USHORT ViewModes;
In this variable you can set the display resolution mode
for your screen.
USHORT Type;
This variable sets the type of screen and must always be
specified as CUSTOMSCREEN. When you initialise your own
bitmap you also have to set the CUSTOMBITMAP flag.
struct TextAttr *Font;
If you want to use a different font with your screen you
can select it here. Simply define a TextAttr structure
describing the new font and provide the address. This
screen and any windows within it will use the selected
font. To use the default font (Topaz) set this variable
to zero.
UBYTE *DefaultTitle;
As with windows, this pointer points to a title text
string for the top screen row of your screen. (The
Workbench screen has the title "Workbench screen"). If you
do not want a title set this pointer to zero.
PAGE 515
-----------------------------------------------------------------------------
struct Gadget *Gadgets;
Currently this pointer is not used and should be set to
zero for guaranteed upward compatibility.
struct BitMap *CustomeBitMap;
This pointer points to your bit-map when Type is set to
CUSTOMBITMAP.
}
The NEWSCREEN structure is used to describe a screen. It is opened with
Screen = OpenScreen (&NewScreen).
--------------------------------------------
struct RastPort
{
struct Layer *Layer;
This pointer points to the Layer structure of the
RastPort. Layers are data structures that help manage
windows. They prevent a window from overwriting another
by mistake.
struct BitMap *BitMap;
This is the pointer to the BitMap used by the RastPort. For
screens other than Intuiton this must be initialised later.
USHORT *AreaPtrn;
This pointer points to the fill pattern of the RastPort.
Normally an area is filled without any special pattern, but
by using the macro SetAfPt() you can change the fill pattern.
struct TmpRas *TmpRas;
This pointer points to an additional memory area that is
used for the fill functions Area...() and Flood. This area
must be large enough to store the entire area that is being
filled.
struct AreaInfo *AreaInfo;
This pointer is only used by the Area().. commands. The
points for a polygon set by AreaDraw() and AreaMove()
must be stored in some location. Use InitArea() to
initialise an AreaInfo structure that contains sufficient
memory (five bytes per coordinate). Then link this structure
to the RastPort for get AREA(RastPort.AreaInfo =
&AreaInfo).
struct GelsInfo *GelsInfo;
This structure is used to display vsprites and bobs in a
RastPort. It contains a linked list of all the graphic
elements for Vsprites. You can sort and display this list
by using SortGList() and DrawGList().
PAGE 516
-----------------------------------------------------------------------------
UBYTE Mask;
This variable contains information about which bitplanes
of a RastPort are affected by a graphic operation. The
normal value is 0xff which means all bitplanes are affected
(each set bit represents an on bitplane). You can change
this variable as required with SetWrMsk(&RastPort, Mask)
BYTE FgPen;
This variable contains the number of the color register
that is responsible for setting the APen colour. FGPen ==
APen, the APen was previously named ForegroundPen.
BYTE BgPen;
BgPen == BPen. (Bpen was the BackgroundPen).
BYTE AOIPen;
AOIPen (Area Outline Pen) == Open
BYTE DrawMode;
This variable contains the actual drawing mode set by the
macro SetDrMd().
BYTE AreaPtSz;
This variable contains the number of rows that are in the
fill pattern. This can always be changed by using SetAfPt(),
but remember that the height must be set in powers of two.
BYTE linpatent;
This help variable is used for drawing lines.
BYTE dummy;
USHORT Flags;
These variables contain various flags. For example, they
can determine whether the first pixel of a line is drawn
(FLAGS \= FRST_DOT) or if only one pixel per raster row
is drawn (ONE_DOT). Another example is whether Area..()
frames an area with the color of the OPen (Flags \=
AREAOUTLINE).
USHORT LinePtrn;
This variable contains the 16 bit line pattern that can be
set with the macro SetDrPt().
SHORT cp_x, cp_y;
These two variables contain the X and Y position of the
graphic cursor, which you can position within the bitmap
with the Move() Command.
UBYTE minterms[8];
We do not have much information for this and the following
two variables. The reason for this is that these parameters
dont provide any visible results when they are changed.
PAGE 517
-----------------------------------------------------------------------------
SHORT PenWidth, /* See minterms */
SHORT PenHeight, /* See minterms */
struct TextFont *Font;
This pointer points to the TextFont structure for the font
currently in use. When the normal font "topaz.font"
becomes tiresome you can change fonts by using OpenFont()
and SetFont().
UBYTE AlgoStyle;
This text contains the text style that you set with
SetSoftStyle().
UBYTE TxFlags;
This variable contains the flags that define your font in
detail for the RastPorts. Here you can determine whether
a font supports proportional characters (TxFlags ==
FPF_PROPORTIONAL), is loaded from RAM (FPF_ROMFONT) or
from disk (FPF_DISKFONT).
UWORD TxHeight;
This variable provides the character height of the current
RastPort font.
UWORD TxWidth;
This is the average width of the individual characters.
UWORD TxBaseline;
This variable contains the position of the baseline for the
font. With the style FPF_UNDERLINED the baseline is drawn
in with each character for underlining. The most important
aspect of the baseline is text positioning with Text().
Strings are not positioned by using a Y position for the
top line of the text. The string is positioned by a Y
position of the graphic cursor and the baseline.
WORD TxSpacing;
This variable sets the pixel width for each character (the
width of a character). This apllies to the display of single
characters but not strings.
APTR *RP_User;
This variable is reserved for the user. You can use this
variable, for example, to link your own data structures with
the RastPort for special purposes.
PAGE 518
-----------------------------------------------------------------------------
UWORD wordreserved[7]; /* reserved */
ULONG longreserved[2]; /* reserved */
UBYTE reserved[8]; /* reserved */
}
When changing a bitmap, The RastPort structure is the most important
structure. Most graphic commands require a RastPort structure because
the actual values of the foreground pen and many other variables are
available
After initialising the RastPort with InitRastPort (&RastPort), simply
initialise the bitmap pointer with RastPort.BitMap = &BitMap.
--------------------------------------------
struct Rasinfo
{
struct RasInfo *Next;
When you have set your ViewPort for DUALPF display mode
(Dual Playfields) you also have to specify two bitmaps that
overlap in the ViewPort. Here you link two RasInfo
structures that point to one of the two BitMaps by using
RasInfo1.Next = &RasInfo2. Then the first of the two
RasInfo structures is made available to the ViewPort with
ViewPort.RasInfo = &RasInfo1;. The rest happens as usual
when opening the View and ViewPorts.
struct BitMap *BitMap;
This is the pointer to the bitmap of the RasInfo structure
that will be displayed in the ViewPort.
SHORT RxOffset, RyOffset;
These two variables determine which pixel of the BitMap
lines up with the upper left corner of the ViewPort. They
are normally set to zero which means that the upper left
corner of the BitMap and the ViewPort line up exactly. By
changing these values and then calculating a new Copper
list you can achieve a scrolling bitmap.
}
The RasInfo structure is the referee between ViewPort and BitMap.
--------------------------------------------
struct Screen
This structure which is similar to the window structure, provides access to
an already opened screen (Screen = OpenScreen(&NewScreen). All system
structures, such as those used for graphic output (Screen->RastPort.xxx,
Screen.ViewPort.xxx etc...), are available to you through this structure.
PAGE 519
-----------------------------------------------------------------------------
struct SimpleSprite
{
UWORD *posctldata;
This pointer points to a memory area in this form;
struct SpriteData
{
UWORD posctl[2];
/* represents the hardware register
'spr[x].pos' and 'spr[x].ctl' )
UWORD Appearance[Height*2];
/* This array contains the appearance of */
/* the sprites row for row defined in */
/* Two UWORDs */
UWORD reserved[2] = {0,0};
}
You must create the spritedata structure yourself because it does
not exist in an include file.
UWORD Height;
This variable contains the height of the sprites. Sprites
are always 16 pixels (1 word) high.
UWORD x,y;
These two variables contain the current position of the
sprites.
UWORD num;
This variable contains the number of the hardware sprites
(0-7) that are described and changed by the SimpleSprite
structure.
}
The SimpleSprite structure permits the use if a hardware sprite. Sprites are
always 15 pixels wide and can be any desired height.
You, as the programmer, must provide the strutures that determine the
appearance of the sprites (SpriteData). Then use SimpleSprite.posctldata =
(UWORD *) &SpriteData to pass this data to the SimpleSprite structure.
--------------------------------------------
struct TextAttr;
{
STRPTR ta_Name;
This pointer points to the name of the font ("name.font")
that you want to open with OpenFont() or OpenDiskFont().
PAGE 520
-----------------------------------------------------------------------------
UWORD ta_YSize;
This is where the height in rows is stored for your font.
UBYTE ta_Style;
You use this variable to set a beginning style for the
font you opened above.
UBYTE ta_Flags;
This variables tells you whether or not your font can use
proportional characters.
This structure is used by the command OpenFont() and OpenDiskFont(). The
variables ta_Name and ta_YSize are used to try to load a specific font and
also find a font that best fits your selected parameters.
--------------------------------------------
struct TextFont
This structure is used to access a font opened with OpenFont() or
OpenDiskFont(). It can be linked to a RastPort with SetFont() or added
to the system font list with AddFont() amd removed with RemFont().
--------------------------------------------
struct TmpRas;
The TmpRas structure is used by the fill commands Flood and Area.. It
must be initialised with InitTmpRas and linked to a RastPort. Now you can
use the Area... and Flood commands with this RastPort.
The TmpRas structure is used to make an area of memory available for use.
It must be large enough to store a bitplane of the largest element you
want filled. This is a requirement of the recursive fill algorithm.
--------------------------------------------
struct View
{
struct ViewPort *ViewPort;
This is the pointer for the first ViewPort of the View.
struct cprlist *LOFCprList;
This is the pointer to the Copper list created with
MrgCop().
struct cprlist *SHFCprList;
This is also a pointer to a copper list, but this list is
only used with interlace mode and is required because
LOFCprList is always used.
PAGE 521
-----------------------------------------------------------------------------
short DyOffset, DxOffset;
These two variables determine the position of your View on
the monitor. They are automatically set by InitView() so
you dont have to worry about the View programming.
UWORD Modes;
This variable contains the resolution mode of the View. In
order to use the interlace mode in any particular View, you
must set it here.
}
The View structure is the manager of graphic displays and provides the most
important link between you and the system.
--------------------------------------------
struct ViewPort
{
struct ViewPort *Next;
Since it is possible to display more than one ViewPort in
a View, this is the pointer to the next ViewPort. The
ViewPorts must also be linked together. After using
InitVPort() this pointer equals zero which means that
there are no other ViewPorts.
struct ColorMap *ColorMap;
This pointer determines the ColorMap of the ViewPort.
Because every ViewPort has its own colormap it is possible to
set different colours for each ViewPort within a View.
struct CopList *DspIns; /* Display instructions */
struct CopList *SprIns; /* Sprite Instructions */
struct CopList *ClrIns; /* Sprite Instructions */
struct CopList *UCopList *UCopIns;
These are the pointers to the intermediate or ViewPort
Copper list created with MakeVPort().
SHORT DWidth, DHeight;
These two variables determine the height and width of the
ViewPort in pixels. For example, the number of lines used
for this ViewPorts resolution (hi-res or lace).
SHORT DxOffset, DyOffset;
These two variables determine the position of the ViewPort
within the View. InitVPort() sets these equal to zero, so
you will have to change them.
UWORD Modes;
This is where you set the resolution mode of the ViewPort.
You are not limited in choice since HAM, Extra Halfbrite,
sprites and all the modes are available. Remember to always
use the highest resolution mode that you will be using in
your View.
UWORD reserved;
struct RasInfo *RasInfo;
This pointer makes the link between ViewPort and bitmap
through the RasInfo structure.
}
The ViewPort that is described by the ViewPort structure is the window
through which you can see your bitmap on the monitor.
PAGE 522
-----------------------------------------------------------------------------
struct VSprite
{
struct VSprite *NextVSprite;
struct VSPrite *PrevVSprite;
These two pointers are used to create the GEL list which is
sorted using SortGList() by X and Y values (See below for
display).
struct VSprite *DrawPath;
struct VSprite *ClearPath;
These pointers are used to display the bobs in an organised
manner. DrawPath writes the bobs into the RastPort.
ClearPath is calculated from DrawPath and, as desired,
removes the bobs from the RastPort and restores the
background.
WORD OldY, OldX;
These two pointers are used to restore the background
covered by a bob when a bob moves. By setting the SAVEBACK
flag in the the VSprite structure for a bob and defining a
memory buffer area, you can save the background that is
hidden when a bob is displayed. When you move the bob and
call DrawGList(), the old background is displayed again. The
old bob position is stored in OldX and OldY so the computer
knows where to restore the background.
WORD Flags;
This variable determines how the system handles the Vsprite.
When the VSprite structure is being used to display
vsprites then Flags = VSPRITE. However, bobs also use this
structure.
WORD Y,X;
These two variables determine the position of the VSPRITE
or bob on the screen.
PAGE 523
-----------------------------------------------------------------------------
WORD Height;
This variable sets the number of vertical rows for a
vsprite or Bob.
WORD Width;
This variable determines how many words are used to display
one row of a bob. A value of one is used for width when
using vsprites because they cannot be wider than 16 pixels
( = 16 bits = 1 word).
WORD Depth;
This is where you set the bitplanes for the bob. This is
actually how many bitplanes you have defined for the bob.
Please note that your bob cannot have a depth greater than
the RastPort in which it is used. However, a bob can have
less bitplanes than the RastPort.
WORD MeMask;
WORD HitMask;
You use these two variables to determine which collision
routine (if any) is executed upon a collision with another
GEL. The MeMask of one and the hitmask of the other GEL
are ANDed and the result bit determines which collision
routine is used. (bit 1=> routine 1, bit2 => routine2, ...
bit 15 => routine 15).
When you set bit zero in HitMask , a GEL border collision
calls routine zero.
WORD *ImageData;
This pointer points to the bob/vsprite data that determine
their appearance. This data must be stored in chip memory.
WORD *BorderLine;
WORD *CollMask;
These two pointers point to memory buffer areas, defined by
you, for the BorderLine and CollisionMask. They are also
used to detect collisions.
The Borderline contains as many words as the width of a
bob or vsprite (vsprites are always one word wide).
Borderline os a logical OR of all the GEL rows. The ColMask
is exactly the same size as your GEL, but is only one
bitplane deep. ColMask contains a logical OR of all plane
data. (Both of these buffers must be created by you and are
initialised with InitMasks(). They must also be located in
chip memory.
WORD *SprColors;
This pointer points to a three UWORD memory area that
contains the VSprite colors.
PAGE 524
-----------------------------------------------------------------------------
struct Bob *VSBob;
If you dont set the VSprite.Flag in the VSprite.Flags
variables, the system assumes that your vsprite structure
is being used to describe a bob. This pointer points to the
bob structure of the vsprite.
BYTE PlanePick;
BYTE PlaneOnOff;
These two variables determine which bit-planes are on
(PlanePick) for displaying your bobs and which are passive
and written with the Bobs ImageShadow.
VUserStuff VUserExt;
With the help of this "extension", the user can combine
his own data into the vsprite. The VUserStuff function
can be defined at any point before the #include statements
are executed (e.g. #define VUserStuff struct Speed (vx,vy);
}
The vsprite structure is needed for both types of GELs. Both the vsprite
itself and the bob are applications of this structure.
--------------------------------------------
struct Window
When you open a new window using WINDOW = OpenWindow(NewWindow), you can
write in the window, bypassing the window structure. This is because you
have a RastPort available (Window->RastPort).
In addition, you can get the window information from Intuition. However,
a detailed description of this will go far beyond the scope of this
Appendix.
PAGE 525
-----------------------------------------------------------------------------
APPENDIX B - THE LIBRARY FUNCTIONS
This appendix provides the C programmer with information about the
library routines used in this book.
First you must open the required libaries (with Openibrary()) before you
can use the library routines.
We have organised the following routine listing by library and in
alphabetical order.
GFXBASE: First the GfxBase routines :
------------------------------------------------------------------
AddAnimOb(&AnimOb, &AnimKey, &RastPort)
These routines are used to organise, in the GEL list of a specific
RastPort, all the bobs for the animation object. This makes it
possible for DrawGList() to draw the bobs in an orderly manner.
The AnimKey points to the last added AnimOb. AnimKey must be equal
to zero for the first AddAnimOb() call (struct AnimOb*AnimKey = 0).
------------------------------------------------------------------
AddBob(&Bob,&RastPort)
This routine adds the specified bob structure for the defined bob
(Blitter object) to the GEL list for the selected RastPort. You
must do this so the bob can later be drawn with DrawGList().
See: AddVSprite(), DrawGList(), SortGList(), InitGList()
------------------------------------------------------------------
AddFont(&TextFont)
This function links the specified TextFont structurem which defines
your font, with the SystemFontList.
Once this is done, your font is available to any program you are
using.
PAGE 527
-----------------------------------------------------------------------------
AddVSprite(&VSprite,&RastPort)
This routine adds the specified vsprite structure, which defines
your vsprite (virtual sprite), to the GEL list of the selected
RastPort. This is needed so that DrawGList() can later display
your Vsprite.
See: AddBob(), DrawGList(), SortGList(), InitGList()
------------------------------------------------------------------
Pointer = AllocRaster(Width, Height)
This function enables you to allocate a memory area for a bitplane
in a size specified by the width and height. After calling this
routine, the first word of the memory address is returned in
pointer.
See: FreeRaster()
------------------------------------------------------------------
Animate(&AnimOb,&RastPort)
This routine applies to all animation objects that are linked to
an AnimOb. Animate calculates the new object positions and resets
Timer for the animation components. In a ring animation
(AnimComp.Flags = RINGTRIGGER), when Timer for a component is equal
to zero the next sequence is activated.
See: AddAnimOb()
------------------------------------------------------------------
AreaDraw(&RastPort,x,y)
This function adds a polygon to the AreaInfo structure for the
specified RastPort. X and Y determine the coordinates of this
point in the BitMap.
See: AreaMove(), AreaEnd(), InitArea()
PAGE 528
-----------------------------------------------------------------------------
AreaEnd (&RastPort)
This function executes the drawing of a polygon, which is defined
with AreaMove() and AreaDraw(). It also fills the polygons with the
current fill pattern controlled by the current APens, BPens, OPens
and Draw modes.
The APen and BPen determine the color of the fill pattern. The
OPen sets the framing colour for the polygon.
Remember that you must first initialise an Area and TmpRas structure
in the RastPort where the polygon will be drawn. Unless you do
this first, filling an area using the Area... function will not
function.
See: AreaDraw(), AreaMove(), InitArea(), InitTmpRas.
------------------------------------------------------------------
error = AreaEllipse(&RastPort, XMiddle, YMiddle, XRadius, YRadius)
This function allows you to draw an ellipse in the selected RastPort.
The centre is at XMiddle,YMiddle. XRaduis and YRadius set the
radius for the ellipse. (When XRadius = YRadius a filled circle
is drawn. Remember that XRadius and YRadius must be greater than
zero).
AreaEllipse is an expansion of the Area.. function. This means that
a filled ellipse is drawn using the current fill pattern.. It also
means that an AreaInfo amd TmpRas structure must exist in the
selected RastPort.
The variable ERROR provides information about the vector table,
which contains the coordinates for the polygon plot points in
AreaInfo. It tells you whether or not there is enough room
(minimal (2+1)*5 bytes) for the data required for an ellipse
(error = 0). If ERROR returns a -1 there isnt enough room.
You must call AreaEnd() to execute the drawing of the ellipse.
See: AreaDraw(), AreaEnd(), AreaMove(), InitArea(), InitTmpRas.
PAGE 529
----------------------------------------------------------------------------
AreaMove(&RastPort,x,y)
AFter building your polygon with AreaDraw(), close it with this routine.
Any additional AreaDraw() functions will start a new polygon with the
above coordinates.
See: AreaDRaw(), AreaEnd(), InitArea()
------------------------------------------------------------------
AskFont(&RastPort, &TextAttr)
This function initialises, in the selected RastPort, the specified
TextAttr structure with the values of the current font. You can
use this function to check the RastPort for the currently active
font.
See: SetFont()
------------------------------------------------------------------
Style = AskSoftStyle(&RastPort)
This function moves, into the selected RastPort, all the possible
font styles that can be set with AskSoftStyle. Each set bit in
style represents a font style:
FSF_UNDERLINED = Bit 0 = 1 (Underlined)
FSF_BOLD = Bit 1 = 2 (Bold)
FSF_ITALIC = Bit 2 = 4 (Italic)
FSF_NORMAL = No set bit = 0
See: SetSoftStyle()
------------------------------------------------------------------
BitPlanes = BltBitMap(&SourceBitMap,X1,Y1,&TargetBitMap,X2,Y2,Width,
Height,Minterm,Mask,Buffer).
This function blitters a rectangle from one bitmap into another
bitmap. You must specify the source rectangle coordinates from the
SourceBitMap(X1,Y1) and the position for the rectangle in the
TargetBitMap(X2,Y2). Since the width and the height are the same for
both rectangles, they are set only once. You must reference both the
source and target bitmaps. Remember that these can also be references
within the same bitmap.
PAGE 530
-----------------------------------------------------------------------------
You also specify the minterm which determines how the source and
target rectangles are logically mixed. What the minterms do and
which ones exist is discussed in Chapter 16.
The Mask parameter determines which bitplanes are blittered. The
default value is $ff which means that all bitplanes are referenced.
You can also filter out specific bitplanes by clearing the
corresponding bit (bit zero for bitplane zero etc.).
Buffer points to a memory area that is used when a target and source
rectangle overlap in the same bitmap. This buffer must have enough
memory to store one row of the rectangle. When you are sure that the
two rectangles do not overlap, you can set the pointer to zero.
The result returned by this function is from the "Blit" affected
bitplanes (see Mask).
Remember that this routine doesnt test whether the target
rectangle fits completely within the target bitmap. It is possible
to blitter over the edge of a bitmap. This can cause errors which
results in less bitplanes being affected than expected. With
extreme error conditions you will encounter the familiar Guru
Meditation.
See: ClipBlit()
------------------------------------------------------------------
BltBitMapRastPort(&SourceBitMap,X1,Y1,&TargetRastPort,X2,Y2,Width,
Height,Minterm)
This function performs exactly the same operation as BltBitMap().
This time you are moving a rectangle from a bitmap into a
RastPort.
The Mask and Buffer parameters are not required here.
THe result returned by this function is TRUE = successful,
FALSE = error.
See: BltBitMap()
------------------------------------------------------------------
BltClear(&Memory, NumBytes, Flags)
As the name indicates, this function erases a selected memory area.
You simply specify the starting address.
The flag parameter determines how the NumBytes value is interpreted:
PAGE 531
-----------------------------------------------------------------------------
With bit one of the flag parameter set to 1:
The upper 16 bits of NumBytes is the number of lines to erase.
The lower 16 bits of NumBytes is the number of bytes per line
to erase.
Width bit one set to zero NumBytes represents the actual number of
bytes to erase.
Bit zero of the flags parameter determines whether the function is
immediately return to the program or wait until the blitter has
erased everything.
------------------------------------------------------------------
BltTemplate(&Source, BitPosition, Modulo, &RastPort, X, Y, Width,
Height)
This function uses the blitter to transfer data from a packed
array into a RastPort. You provide the address of the packed
array and the bit position within this array, where the data
read should start.
Modulo specifies the number of bytes for one row in the data array.
X,Y, width and height set where and how much data from the array is
moved to the RastPort.
------------------------------------------------------------------
ChangeSprite(&ViewPort,&Sprite,&SpriteData)
This function changes the appearance of the specified hardware
sprites. Remember that the hardware sprite must be initialised
already. This ensures that the height and screen position are already
set and that the correct hardware sprite (SimpleSprite.num) is
affected.
The data used by this function have the following format:
struct SpriteData
{
UWORD posctl[2];
UWORD Data[Height][2];
UWORD Reserved[2]; /* = 0,0 */
}
posctl represents the sprite hardware register spr[x].pos and
spr[x].ctl. This allows the user to use GetSprite() to reserve both
the even and odd numbered sprites and set the SPRITE_ATTACHED bit in
posctl[l] for attached sprites. When the bit pattern of both sprites
overlap, they are merged. This permits the use of 15 colors instead
of only three (plus transparent).
See: GetSprite(), FreeSprite(), MoveSprite()
PAGE 532
-----------------------------------------------------------------------------
ClearEOL(&RastPort)
This function deletes one row, in the selected RastPort, that has
the height of the character in the current font. This deletion
starts at the current graphic cursor position (RastPort.cp_x,
RastPort.cp_y).
See: ClearScreen(), Move()
------------------------------------------------------------------
ClearScreen(&RastPort)
In contrast to the ClearEOL() function, which only clears one row,
ClearScreen deletes the entire RastPort from the current graphic
cursor position.
See: ClearEOL(), Move()
------------------------------------------------------------------
ClipBlit(&SourceRastPort,X1,Y1,&TargetRastPort,X2,Y2,Width,Height,
Minterm)
This function performs exactly the same function as BltBitMap().
Most of the parameters have the same meaning. But with this function
we blit from one RastPort to another and any overlapping problems
are handled by the routine.
This function is much better because it is easy to use (you do not
have to reserve a buffer) and it prevents you from creating any
error conditions. Blitting over the border of a RastPort does not
create the problems possible with BltBitMap().
See: BltBitMap(), BltBitMapRastPort()
------------------------------------------------------------------
CloseFont(&TextFont)
When you have opened a font with OpenFont() or OpenDiskFont() you
must also close it again before ending your program. Otherwise the
memory used by your font is not released back to the system.
See: OpenFont()
PAGE 533
-----------------------------------------------------------------------------
DisownBlitter()
This function releases the blitter from your control and allows
other programs to use it again.
See: OwnBlitter()
------------------------------------------------------------------
DoCollision(&RastPort)
This routine tests all GELs in the GEL list for a RastPort, for
collisions and also executes any collision routines you have set up
with SetCollision().
However, we must inform you that DoCollision() does not function all
the time.
See: SetCollision.
------------------------------------------------------------------
Draw(&RastPort,x,y)
This is one of the most important graphic functions. DRAW allows
you to draw a line from the current graphic cursor position to the
selected X/Y coordinate in the specified RastPort.
See: Move()
------------------------------------------------------------------
DrawEllipse(&RastPort, XMiddle, YMiddle, XRadius, YRadius)
This function allows you to draw ellipses or, with XRadius =
YRadius, circles. These are not filled as with AreaEllipse; only
the outline is drawn.
Remember that XRadius and YRadius must contain values that are
greater than zero.
PAGE 534
-----------------------------------------------------------------------------
DrawGList(&RastPort,&ViewPort)
DrawGList() performs two functions. First it can draw the bobs, from
the GEL list in the selected RastPort. Second, it can link the
vsprites, from the ViewPort copper list, with the Selected ViewPort.
However, vsprites are not drawn after calling DrawGList(). First
you have to use MakeVPort() or MakeScreen() to set up the new Copper
list. Then you use MrgCop() and LoadView() or RethinkDisplay to
display them.
See: MakeVPort(), MrgCop(), LoadView(), MakeScreen(),
RethinkDisplay()
------------------------------------------------------------------
Flood(&RastPort, Mode, x, y)
This function enables you to fill an area in a RastPort. All the
pixels around the area from the specified X/Y positions are tested
and filled according to the mode selected. Mode = 0 tests for the
colour of the Open and mode=1 tests for the color of the starting
pixel.
Any pixels around your starting point that dont meet the
requirements of either mode are filled with the current fill
pattern. When the pixel meets one of the mode criteria it is not
changed.
When all pixels within a closed border meet the mode criteria and
are already filled, the fill is cancelled.
Remember that for the Flood() function a TmpRas structure must be
initialised and must have enough memory to be used by the Flood()
function.
See: InitTmpRas()
------------------------------------------------------------------
FreeColorMap(&ColorMap)
You use this function to release the memory, which was reserved
through GetColorMap() for the ColorMap structure, back to the
system.
See: GetColorMap()
PAGE 535
-----------------------------------------------------------------------------
FreeCopList(&CopList)
Call this routine in order to release a single intermediate Copper
list for a ViewPort (struct CopList), which was created by using
MakeVPort(). FreeVPortCopList() uses this routine to release all
intermediate lists from a ViewPort.
See: FreeVPortCopList()
------------------------------------------------------------------
FreeCprList(&cprlist)
Use this function to release the memory reserved, through
View.LOFCprList and View.SHFCprList, for the hardware Copper list.
These hardware copper lists are calculated from the individual
ViewPort Copper lists by using MrgCop().
See: MrgCop()
------------------------------------------------------------------
FreeRaster(&BitPlane, Width, Height)
This function produces the opposite effect of AllocRaster(). It
releases all reserved bitplane memory, that was allocated with
AllocRaster(), back to the system. This makes the memory available
to other programs again.
BitPlane points to the memory area that you reserved with
AllocRaster. Width and Height must be the same for free and
AllocRaster(), otherwise it is possible to release too much or too
little memory.
See: AllocRaster()
------------------------------------------------------------------
FreeSprite(SprNumber)
With FreeSprite you can release a sprite, that was reserved
specifically for your through GetSprite() back to the system.
This makes the sprite available again for full system use
(especially the vsprites).
You just provide the number of the sprite that was reserved with
GetSprite().
PAGE 536
----------------------------------------------------------------------------
See: GetSprite(), ChangeSprite(), MoveSprite()
------------------------------------------------------------------
FreeVPortCopLists(&ViewPort)
With this function you can release, for the specified ViewPort that
you generated with MakeVPort(), all the Copper lists for the
colour, display, sprites etc...
See: MakeVPort(), FreeCopList()
------------------------------------------------------------------
*ColorMap = GetColorMap(NumberColors)
This function create a complete ColorMap structure. All of the
required ColorMap structure variables are initialised and enough
memory is reserved for the specified NumberColors. When sufficient
memory is not available for the new ColorMap structure or color
buffer, a ZERO(0) is returned by the routine.
You must link this ColorMap structure to the ViewPort with
ViewPort.ColorMap = ColorMap(before using MakeVPort() to calculate
the Copper list for the ViewPort).
See: FreeColorMap(), LoadRGB4(), GetRGB4(), SetRGB4()
------------------------------------------------------------------
Color = GetRGB4(&ColorMap,ColorRegister)
This function enables you to retrieve the UWORD that determines
the color of the selected color register. The 16 bit UWORD
which is returned is divided as follows: bits 0-3 are the blue
component, bits 4-7 the green and bits 8-11 red.
See: SetRGB4(), LoadRGB4()
------------------------------------------------------------------
SprNumber = GetSprite(&SimpleSprite,getSprNumber)
This function allows you to reserve any hardware sprite for your
personal use. You provide the SimpleSprite structure, that the
sprite will be associated with, to the function. Also, select the
desired number (0-7) (if it doesnt matter a -1) of the reserved
sprite.
The number of the reserved is returned is returned in the
SpriteNumber. If the selected sprite is not available, SpriteNumber
contains a -1.
See: FreeSprite(), MoveSprite(), FreeSprite()
PAGE 537
-----------------------------------------------------------------------------
InitArea(&AreaInfo,&Buffer,NumCoord)
This function initialises the selected AreaInfo structure for you.
The structure contains the specified Buffer and the NumCoord+1
coordinates required for AreaDraw() and AreaMove(). The buffer
should contain at least five time the number of bytes that are
required for the polygon coordinates which are used with AreaMove()
and AreaDraw().
Declaring the buffer as a char array is the easiest method. Since
programs created with the compiler automatically releases arrays,
you dont have to release the used buffer area again.
See: AreaDraw(), AreaMove(), AreaEnd()
------------------------------------------------------------------
InitBitMap(&BitMap, Depth, Width, Height)
This routine initialises the specified BitMap structures. The
depth (number of bitplanes), width (in pixels), and the height
(in rows) is easily set.
See: AllocRaster()
------------------------------------------------------------------
InitGels(&Begin, &End, &GelsInfo)
This function initialises the selected GelsInfo structure. You need
this structure in order to display vsprites and bobs in an organised
manner.
All the graphic elements (=GEL) are linked in a list through the
vsprite structures (&Begin, &End). &Begin and &End mark the
beginning and end of this GEL list.
After you have used InitGels() to initialise the GelsInfo structure,
then simply make them available to your RastPort (RastPort.GelsInfo =
&GelsInfo). Once this is accomplished, you can start displaying
your bobs and vsprites.
See: AddVSprite, AddBob()
PAGE 538
-----------------------------------------------------------------------------
InitMasks(&VSprite)
You initialise the BorderLine and CollMask for the specified
vsprite structure with this routine. The memory buffer for both
masks must be reserved already and stored in the variables
VSprite.BorderLine and VSprite.CollMask.
------------------------------------------------------------------
InitRastPort (&RastPort)
You use this routine to initialise the specified RastPort
structure. This RastPort structure is the most important connection
between the user and BitMap.
The RastPort contains, for example, the color of the current
foregroundpen(APen). It also contains a pointer to the bitmap
where the graphic functions will be executed and many other
important variables and pointers used by the graphic functions.
------------------------------------------------------------------
TmpRas = InitTmpRas(&TmpRas,&Buffer,BufferSize)
When you use the Area...() functions within a RastPort, an extra
memory area is required for these functions. This buffer must be
at least as large as the object being filled. Because of the
recursive algorithm used by fill, extra memory is required as
workspace.
This buffer only requires one bitplane which is as large as the
largest element. To ensure that you have enough, it is best to
reserve one complete bitplane for the temporary raster.
Now simply pass the initialised TmpRas structure to your RastPort.
There are two possible ways to do this. You can either use the
result returned by the initialised TmpRas structure (RastPort.
TmpRas= InitTmpRas (....)) or pass the initialised TmpRas structure
yourself (RastPort.TmpRas = &TmpRas).
PAGE 539
-----------------------------------------------------------------------------
InitView(&View)
This function is used to initialise the specified View structure.
All variables and pointers for the View structure are first set
to zero. Then the DxOffset and DyOffset variables are set so that
the View is positioned approximately two centimetres below the top
right monitor border. This assumes that the monitor is properly
adjusted.
See: MrgCop(), MakeVPort()
------------------------------------------------------------------
InitVPort(&ViewPort)
This function is used to clear all variables and pointers for the
selected ViewPort structure. This is done so that the individual
Copper lists for this ViewPort will be correctly calculated with
MakeVPort(). When a pointer to a ViewPort Copper list is not equal
to zero, MakeVPort() assumes that a ViewPort Copper list exists
and does not calculate a new one.
Undefined Copper lists could be created without this MakeVPort()
feature.
See: MakeVPort()
------------------------------------------------------------------
LoadRGB4(&ViewPort,&Colotpalette[0],Colorentry)
This routine allows you to load new colour values, ColorEntry from
the ColorPalette (UWORD Colorpalette[Colorentry];) into the
ColorMap for the selected windows.
Using this routine is an easy way to change all the colours of a
ViewPort at one time. However, the change is not immediate. First
you have to calculate a new color Copper list for the ViewPort. You
do this with MakeVPort(), MrgCop() and then LoadView(). When using
intuition screns substitute RemakeDisplay() for LoadView().
See: SetRGB4(), GetRGB4()
PAGE 540
-----------------------------------------------------------------------------
LoadView(&View)
After calling this function, the selected View and all ViewPorts
it contains are displayed on the screen. You must first use
MakeVPort() for each ViewPort that will be displayed in the View.
MakeVPort() creates the ViewPort Copper lists that MrgCop() merges
into a single View Copper list.
The View Copper list starting address is written by LoadView() in
the necessary hardware registers (cop11c, cop21c).
See: InitView(), InitVPort(), MakeVPort(), MrgCop()
------------------------------------------------------------------
MakeVPort(&View,&ViewPort)
This routine calculates the intermediate ViewPort Copper lists for
the selected ViewPort of the specified View. For example, there are
ViewPort Copper lists for color display for all colors which are
written through the Copper to the hardware registers. These color
copper lists are calculated from the ViewPort colormap. When the
color list pointer is equal to zero, the default ColorMap is
used to calculate the ViewPort color Copper list.
These lists also contain the various resolution modes for the
ViewPorts (many ViewPorts in one View can have different
resolutions).
See: MrgCop(), FreeVPortCopLists()
------------------------------------------------------------------
Move(&RastPort,X,Y)
You use this function to position the graphic cursor for the
selected RastPort to the specified position (RastPort.cp_x = x;
RastPort.cp_y = y;)
At this position you could print text or draw a line to another
position.
------------------------------------------------------------------
MoveSprite(&ViewPort,&SimpleSprite, X,Y)
This function lets you position the selected hardware sprites within
the selected ViewPort when ViewPort is not equal to zero. Otherwise,
the sprite will be positioned relative to the View.
X and Y specify the new position. Remember that the position values
in hi-res or lace ViewPorts must be multiplied by two so that the
sprite actually moves.
See: ChangeSprite(), GetSprite(), FreeSprite()
PAGE 541
-----------------------------------------------------------------------------
MrgCop&(View)
This function calculates the View hardware Copper list from the
ViewPort Copper lists created with MakeVPort(). Then this list is
used by the hardware(cop11c,cop21c).
Any change to the colortable or the hardware sprite positions
requires a newly calculated copper list. This happens automatically
when the hardware sprites are moved. When changing the colorpalette
with LoadRGB4() you must update the Copper list.
See: MakeVPort(), FreeCprList()
------------------------------------------------------------------
*TextFont = OpenFont(&TextAttr)
This function searches through the SystemFontList for a font
described by the TextAttr structure. When a font cannot be found
to match the named TextAttr structure, a value of zero is returned.
However, when a font is found but has different styles or sizes, a
font that best meets the specifications is selected.
OpenFont() increases user choices when accessing the Systemfonts.
OpenFont() and CloseFont() must maintain a balance in order to
guarantee a clean memory. When a font is no longer required you
can remove it from memory with RemFont().
See: CloseFont(), AddFont(), RemFont(), OpenDiskFont(),
AvailFonts().
------------------------------------------------------------------
OwnBlitter()
This function informs the Blitter that it is only able to work
for you. Other tasks (programs) that are running at the same time
can no longer use the blitter.
After OwnBlitter(), you should use WaitBlit() to allow the Blitter
to complete any current processing.
See: DisownBlitter(), WaitBlit()
PAGE 542
----------------------------------------------------------------------------
PolyDraw(&RastPort.NumCoords, &PixelArray)
This routine enables you to draw into the selected RastPort by
using coordinates from any array you created. Lines are drawn from
pixel to pixel as plotted from the array.
THe pixels are stored in an integer array (int PixelArray
[NumCoords][2]) with each coordinate consisting of two array
elements. The first element is the X and the second is the Y
coordinate for the stored polygon pixels
NumCoords specifies the number of pixels that will be drawn from
the pixel array.
------------------------------------------------------------------
ColorRegister = ReadPixel(&RastPort, X, Y)
This function allows you to read the color value of a specific
pixel at the coordinates you selected.
When your coordinates are outside the selected RastPort, a value
of -1 is returned in ColorRegister.
See: WriteAPen(), SetAPen()
------------------------------------------------------------------
RectFill(&RastPort, X1, Y1, X2, Y2)
With this function you can fill any desired rectangular area within
the selected RastPort. The current fill pattern, Drawmodes, APens,
etc.. affect how your fill is performed.
You just specify the top left corner (X1,Y1) and the lower right
corner (X2,Y2) of the rectangle you want filled. Make sure that
the lower right corner really is lower and to the right of the
upper left corner. When your coordinates are incorrect the computer
can crash because your memory will be filled without the proper
controls.
PAGE 543
-----------------------------------------------------------------------------
This function does not require a TmpRas structure like the Flood()
and Area...() functions.
------------------------------------------------------------------
RemFont(&TextFont)
This function removes the selected font from the system font list.
The font remains available to any programs currently using it.
After all programs signal, with CloseFont(), that this font is no
longer required, the font is pysically removed from memory.
After you have used RemFont() a program that has used CloseFont()
cannot access the font again.
See: AddFont(); OpenFont(); CloseFont()
------------------------------------------------------------------
RemIBob(&Bob, &RastPort, &ViewPort)
This function immediately removes the selected bob from the GEL,
list for in RastPort and deletes it from the RastPort.
See: DrawGList(), SortGList(), InitGels()
------------------------------------------------------------------
RemVSprite(&VSprite)
This routine deletes the selected vsprite from the current GEL
list. However, the sprite does not immediately dissappear from the
screen. This occurs only after the calls to SortGList(), DrawGList(),
MakeVPort(), MrgCop(), LoadView().
See: DrawGList(), SortGList()
------------------------------------------------------------------
ScrollRaster(&RastPort, DeltaX, DeltaY, X1, Y1, X2, Y2)
This function scrolls the rectangle, specified by X1, Y1, X2, Y2
(see RectFill), for DeltaX pixels and DeltaY rows. Positive delta
values scroll up and left. Negative delta values scroll right and
down. Combatting negative and positive 'Delta' values allows you
to scroll in any desired direction.
PAGE 544
-----------------------------------------------------------------------------
The areas uncoverd by the scrolled rectangle are filled with the
color of the BPen.
Please note that this routine is not very fast and can cause some
flickering during the scrolling.
------------------------------------------------------------------
ScrollVPort(&ViewPort)
After you have changed the RxOFfset and RyOffset values in the
RasInfo structure of the ViewPort, use ScrollVPort() to display
a different portion of the bitmap. ScrollVPort calculates the
new copper list for the new bitmap position.
This routine is not fast enough to prevent some flickering on the
screen. Because of this, you should calculate the new Copper list
since this can be performed as a background process.
------------------------------------------------------------------
SetAPen(&RastPort,Colorregister)
This function allows you to select, in the selected RastPort, a new
color for the APen.ColorRegister selected the number of the colour
register in the ViewPort ColorMap.
See: SetBPen()
------------------------------------------------------------------
SetBPen(&RastPort,ColorRegister)
Just like SetAPen, the color of the BPen is changed in the selected
RastPort. Again, ColorRegister specifies the number of the color
register to be used from this point on.
APen and BPen functions differently depending on which drawing mode
you are using. With JAM2 mode, the BPen functions as the background
color pen. For example, text would be highlighted with the BPen.
The BPen has no effect in other draw modes.
See: SetAPen()
PAGE 545
-----------------------------------------------------------------------------
SetCollision(Number, Routine, &GelsInfo)
After comparing the MeMask and HitMask, this function sets the
collisions routines that are used for collisions between GELs or
a GEL with a border.
With GEL to GEL collisions you must pass both vsprite structures to
your collision routine. The first vsprite structure passed
represents the upper left positioned GEL (bob or vsprite).
With border collisions, you pass the involved vsprite structure
and a flag to your routine. The flag contains the code for the
border (TOPHIT, BOTTOMHIT, LEFTHIT, RIGHTHIT) the GEL collided
with.
See: DoCollision()
------------------------------------------------------------------
SetDrMd(&RastPort, Mode)
Use this function to set the DrawMode for your RastPort. This sets
up how lines are drawn, how pixels are set and how text is
displayed. The following modes exist:
JAM1 (0): Only the APen colour is used for drawing.
JAM2 (1): The BPen colour is used for the background.
COMPLEMENT(2): Pixels to be drawn are first XORed with the
existing pixels (by bitplane).
INVERSVID(4) : Pixels are inverted before being drawn (by bitplane).
The modes COMPLEMENT and INVERSVID only function with JAM1 or
JAM2.
------------------------------------------------------------------
SetFont(&RastPort,&Font)
SetFont() makes a font available to the selected RastPort. This
font should have alreay been opened with OpenFont() or
OpenDiskFont(). Any text you know output with Text() will appear
in the new font.
See: OpenFont(), CloseFont()
PAGE 546
----------------------------------------------------------------------------
SetRast(&RastPort, Colorregister)
This function sets all pixels in the selected RastPort bitmap, to
the color of the colour register from the ViewPort's colormap
for this RastPort.
When ColorRegister equals zero, then all the pixels of the ViewPort's
ColorMap are cleared to colour zero (= background color).
------------------------------------------------------------------
SetRGB4CM(&ColorMap, Colorregister, Red, Green, Blue)
This function works similar to SetRGB4. However, the color change
is not immediately visible. This happens only after you
calculate the Copper list again with RemakeDisplay.
The colour change first occurs in the selected colormap before it
is allowed to be visible.
Like LoadRGB4, the colormap is initialised with new values in the
background.
See: LoadRGB4()
------------------------------------------------------------------
SetRGB4(&ViewPort, ColorRegister, Reg, Green, Blue)
This function allows you to change the color of one color register
in the specified ViewPort. You pass the number of the color register
and the new red, green and blue components (0-15) for the new
color value.
SetRGB4() also changes the color entry in the ColorMap structure of
the ViewPort amd in the Copper list. This colour change is
immediately visible on the screen.
See: LoadRGB4(), GetRGB4()
PAGE 547
-----------------------------------------------------------------------------
NewStlye = SetSoftStyle(&RastPort, FontStyle, Style)
This function sets your desired, algorithmically generated font
style in the selected RastPort. You set the desired style in
FontStyle (see AskSoftStyle()) and use the value returned by
AskSoftStyle in Style. AskSoftStyle() provides the available
styles that can be used for the Style variable. For example,
it is possible that a font is already italic and after
AskSoftStyle() provided that information, it would be useless
to try to make that font italic.
SetSoftStyle() changes a font only when the style-bits are also
set in Style. After the change, NewStyle contains the font
generated by SetSoftStyle().
See: AskSoftStyle()
------------------------------------------------------------------
SortGList(&RastPort)
This routine sorts the GEL list of the selected RastPort. The
vsprite structures used for positioning vsprites and bobs are
sorted by their Y and X coordinates. The sort is performed by the
Y and then by the X coordinate.
After using SortGList() you use DrawGList() to display the GEL
list again.
See: DrawGList()
------------------------------------------------------------------
Text(&RastPort, &"string", NumCharacters)
This routine lets you display, at the graphic cursor position, any
desired text in the selected RastPort. You simply provide the
starting address of the output string and the number of characters
to be displayed.
See: TextLength()
------------------------------------------------------------------
Length = TextLength(&RastPort, &"String", NumCharacters)
This function has the same parameters as Text(). The length in
pixels for the text string is returned and the RastPorts currently
active font is used to display the text.
PAGE 548
See: Text(), SetFont()
-----------------------------------------------------------------------------
Position = VBeamPos()
This function returns the current vertical position of the
electronic raster beam in "position". The values that are returned
fall between 0 and 255 on PAL systems. Because the electron beam
actually scans 262 lines on PAL systems, the positions between
256 and 262 are returned as values between zero and 6.
After your program has received it, the value returned by
VBeamPos() is usually useless. Due to the Amiga's multitasking
capabilities, the millisecond reaction time, required by your
program to react, can be used up by another program or task.
------------------------------------------------------------------
WaitBlit()
This function pauses your program until the blitter has completed
its task. Be careful because a processor error can cause WaitBlit()
to return actually before completing the desired task. Your program
is then able to continue its tasks before they should occur.
Most often, this error occurs when you are using hires with
four bitplanes.
------------------------------------------------------------------
WaitBOVP(&ViewPort)
This function pauses your program until the electron beam reaches
the last row of the selected ViewPort (Bottom of ViewPort).
See: WaitTOF()
------------------------------------------------------------------
WiatTOF()
This function is similar to WaitTOF() except that the pause doesnt
happen until the end of the ViewPort. WaitTOF() waits for the
electronic beam to reach "Vertical Blank" (top of frame) or the
start of a new scan after completing any cyclic routines
(Interrupts)
See: WaitBOVF()
PAGE 549
-----------------------------------------------------------------------------
WritePixel(&RastPort,x,y)
This function sets a pixel at coordinates X and Y, in the APen
colour in the selected RastPort. Naturally, the current drawing
mode of the RastPort is used.
See: ReadPixel()
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
DISKFONTBASE
============
Now to the DiskFontBase functions (you must first open the library
"diskfont.libraries"
----------------------------------------------------------
Error = AvailFonts(&Buffer, BufferSize, Typ)
This function provides a complete list of the available system
fonts. This list is written into the memory area (&Buffer),
which contains the BuffserSize that you selected.
The first thing stored in the buffer is the AvailFontsHeader. This
contains the number of font entries that are stored (in
AvailFontsHeader.afh_NumEntries). Then the various AvailFonts
entries, which contain the type of font, (either in the system font
list (AFF_MEMORY) or on disk (AFF_DISK) and the more descriptiive
TextAttr structure are stored.
The TextAttr structure can be used to open a font. However, this
must be done by type (AFF_MEMORY / AFF_DISK) in order to open one
with OpenFont() or OpenDiskFont().
THe AvailFonts parameter TYP determines whether the Systemfontlist
(AFF_MEMORY), SYS:Fonts (AFF_DISK) or both are searched for
available fonts.
Please note that AvailFonts() does not verify the TextAttr structure
contents for SYS:Fonts from disk. When you open fonts using
OpenDiskFont() with the returned TextAttr structure of AvailFonts(),
you can encounter such undesired results as a system crash.
The results returned by AvailFonts() provide information on whether
or not enough memory is available to store all the AvailFont
structures. When error equals zero there is enough memory. However,
when error is not equal to zero or the number of additional bytes
that are required to contain all the AvailFonts structures is
returned instead.
PAGE 550
-----------------------------------------------------------------------------
*TextFont = OpenDiskFont(&TextAttr)
This function opens a font described by the TextAttr structure.
The SYS:Fonts directory is searched for a font that best matches
the TextAttr structure in style and size. If a matching font in the
TextAttr structure cannot be found, a value of zero is returned.
See: OpenFont.
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
INTUITIONBASE
=============
The following are the IntuitionBase routines (IntuitionBase is the
pointer to the Intuition library that you open with IntuitionBase =
(struct IntuitionBase *) OpenLibrary("intuition.library",0)
--------------------------------------------
CloseScreen(&Screen)
Use this function to close a screen that was opened earlier with
OpenScreen(). The memory used for the bitmap and all Intuition
screen structures (ViewPort, RastPort etc..) is released.
When you close the last user-opened screen, the workbench screen
is automatically active again. CloseScreen() does not check
whether all windows for a screen have been closed. If any
windows are still open a system crash will occur.
See: OpenScreen()
-----------------------------------------------------------------
CloseWindow(&Window)
This function closes a window you have opened with OpenWindow().
Make sure that you close all the windows in a screen before
attempting to close the screen window.
See: OpenScreen()
------------------------------------------------------------------
DisplayBeep(&Screen)
This function blinks the screen by quickly changing the background
color of the screen. This technique is used in order to make the
user aware of small errors.
PAGE 551
-----------------------------------------------------------------------------
By using a zero instead of a screen address you can blink all the
Intuition screens. However, this should only be used to indicate
a rather extreme user error.
------------------------------------------------------------------
MakeScreen(&Screen)
This function executes MakeVPort() for the ViewPort of the specified
screen. You can make changes to the intuition screens' ViewPorts
(such as color changes with LoadRGB4() and inform the copper
afterwards).
See: MakeVPort()
------------------------------------------------------------------
ModifyIDCMP(&Window,IDCMPFlags)
This function is used to change the IDCMP flags (Intuition Direct
Communication Message Ports) for a window. These flags are used
for various messages that are sent by Intuition to your window.
However, it is impossible to explain all the possibilities of the
IDCMP's in this Appendix.
------------------------------------------------------------------
OpenScreen(&NewScreen)
This function opens an Intuition screen that is further described
by the selected NewScreen structure. This function creates a
ViewPort and all the other required structures (bitmap, RastPort,
etc..). The new screen is linked to the Intuition View and
then displayed.
See: CloseScreen().
------------------------------------------------------------------
RemakeDisplay()
This funnction calculates a new Copper list for all intuition
screens. This means that for each screen, a MakeScreen() and
then a ReThinkDisplay() is called. When using this function,
you should disable multi-tasking for a short time.
See: MakeScreen(), ReThinkDisplay()
PAGE 552
-----------------------------------------------------------------------------
ReThinkDisplay()
This function executes MrgCop() and LoadView() for the intuition
View. Multitasking is turned off shortly while this is executing.
See: MakeScreen(), RemakeDisplay(), MrgCop(), LoadView()
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Here are the DosBase routines (Please note that DosBase, just like the
ExecBase, dont have to be opened because in these C programs they are
always open).
Delay(Time)
This routine pauses you program "Time" * 1/60 seconds. Other
running tasks are not paused as with a pause using for().
------------------------------------------------------------------
Exit(ReturnValue)
This function allows you to exit a program loop at any time. When
you run your program as an 'overlay-process', the "return value"
is passed to your main process. We did not use the program overlay
technique in our examlple programs.
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
EXECBASE : The following are the execbase routines:
*Memory = AllocMem(NumBytes,Use)
This routine is used to declare NumBytes of memory for your use.
You must also specify what memory you require. When you use
MEMF_CHIP (MEMF = MEMoryFlag) the memory is allocated from the
lower 512K bytes area. This is especially important since this
memory must be used by all the Amiga processors (for example,
for bitplanes etc..)
With MEMF_PUBLIC you use a memory area from anywhere. This can
be an area above 512k bytes if you have more than 512K.
MEMF_CLEAR allows you to immediately clear the selected memory
area. You will receive the address of a completely cleared memory
area.
See: FreeMem()
PAGE 553
-----------------------------------------------------------------------------
CloseLibrary(&BasePointer)
Use this function to close a library you open earlier with
OpenLibrary(). Provide the address pointer that you received when
using OpenLibrary() in "BasePointer".
Please make sure you close all open libraries before exiting
your program.
See: OpenLibrary()
------------------------------------------------------------------
FreeMem(&Memory, Size)
You use this routine to release a memory area that was reserved.
Simply specify the starting address of the memory area and the
number of bytes reserved.
See: AllocMem()
------------------------------------------------------------------
Message = GetMsg(&Port)
By using this function you can intercept messages from Intuition.
This function waits until a message is sent.
See: AllocMem()
------------------------------------------------------------------
OpenLibrary(&LibName,Versionnumber)
Use this function to open the selected library which gives you
access to specific operating system routines.
For example, to use the graphic functions, open the graphic library
with GfxBase = (struct GfxBase *) OpenLibrary("graphics.
library",0). GfxBase is the pointer to the requested library
and must be used with CloseLibrary at the end of your program.
PAGE 554
-----------------------------------------------------------------------------
When you dont know the actual version number of the library, use
zero, which uses the current library version. However, when a
function is available only in a specific version of a library,
you should quickly exit your program is the library is not found.
------------------------------------------------------------------
ReplyMsg(&Port)
Use this function to tell intuition, for example, that you have
received and processed its messages.
PAGE 555
-----------------------------------------------------------------------------
APPENDIX C - THE HARDWARE REGISTERS
===================================
This appendix provdes an overview of the Amiga hardware registers. Those
registers are useful with Copper programming because they can be easily
changed through the copper.
Use the CMOVE() instruction with the register number that you want to
change. If you want to change a register by using the 68000, you should
only write to specific memory areas.
THe hardware registers are located in a memory area starting at $DFF000.
This means that you must use this address as an offset and then add the
value of the specific register address in order to use the 68000 to
access it.
To access the hardware registers with C, use the Custom structure that
you create with extern struct Custom custom. As with the Copper or
68000, you can access the individual registers by using custom.Name.
The following list describes hardware registers in detail. We have
provided the regsiter number as you would define them in your include
file hardware/custom.h. We also show the offset for each register from
$DFF000. So, both C and machine language programmers have the background
information on the registers and how to use them.
-----------------------------------------------------------------------------
adkcon $09E Audio and disk control (write)
adkconr $010 Audio and disk control (read)
As shown, you access these registers differently. You can either
write (adkcn) to one, or read (adkconr) from the other.
The bit structure of both registers is the same. However, even
though bit 15 is not affected by read operations, it is very
important for write operations.
Bit 15 SET/CLR:
When writing a word with this bit set, all bits (14-0) are written
into the register. Any unset bits in the word being written do
not change the corresponding bit already in the register.
PAGE 557
-----------------------------------------------------------------------------
If bit 15 is unset in the word being written, all set bits of the
written word clear any matching set bits in the register. Again,
any unset register bits are unaffected.
In order to clearly explain this, we have provided the following
short example: When writing the binary value %1111111111111110 all
bits in the register are set except for zero. With a value of
%0111111111111110 all bits in the register are cleared except bit
zero. This type of register control appears very often. Whenever a CLR/SET bit is used, the above rules will apply.
Bits 14,13 PRECOMP1/2:
These bits set the PreComp for disk operations. The value %00 in
both registers selects zero ns (nanoseconds). A value of %01
selects 140ns, %10 selects 280ns and %11 selects 560ns.
Bit 12 MFMPREC:
This bit selects the read format for a disk. If it is set, this
bit selects the normal mfm format. When it is unset, the GCR
format is selected as for Apple or Commodore 64 disks.
Bit 11 UARTBRK:
When this bit is set, all lines of the RS232 interface are set to
zero (Universal Asynchronous Receiver/Transmitter Break).
Bit 10 WORDSYNC:
Setting this bit starts the data transfer over the DMA channel
and each word read is synchronised with the word in DSKSYNC.
Bit 9 MSBSYNC:
This bit determines whether the high bit of a word is synchronised
in GCR format.
Bit 8 FAST
This bit allows you to set the timing for reading a bit from disk.
Setting this bit selects two microseconds, which is the required
timing for the MFM format. A value of zero for this bit sets the
timing to four microseconds, which is the correct timing for
GCR type formats. (Apple, Commodore 64).
Bits 7-4 ATPER3-0:
These bits allow you to modulate the sampling rate of the
inidividual audio channels. Setting ATPER3 stops the sound channel
output. By setting ATPER2, you can modulate the sampling rate of
audio channel three with audio channel two. Setting ATPER1
modulates the sampling rate of audio channel two with audio channel
one. ATPER0 sets the modulation sampling rate between audio
channels one and zero.
PAGE 558
-----------------------------------------------------------------------------
Bits 3-0 ATVOL3-0
These bits determine the volume modulation of the individual audio
channels. The pattern used is the same as ATPER3-0 except that the
volume is modulated.
------------------------------------------------------------------
aud[X].ac_ptr $0A0 Audio channel X start address.
The address for the data that will be sent over the sound DMA
channel (direct memory access = without the use of 68000) is
stored here.
This is actually a register pair where the data address' lower 15
bits are stored in $0A2 and the upper three bits are stored in
$0A0. Based on the custom declaration in the include file, the
*ac_ptr is already reserved by the compiler as a long word.
To directly access this register pair from the C language, you
must use an index value between 0 and 3 for the corresponding
audio channel (aud[X]).
Machine language programmers must always add X*12 words to access
a specific sound channel register. This register pair and the
following five registers represent a block divided into four
parts, one after the other. At the end of this Appendix we have
provided a table showing all the register addresses relative to
$DFF000.
Remember that here you can only use 18 bits for addressing. The
sound chip, as with the Blitter, only uses the lower 512k bytes
of memory.
------------------------------------------------------------------
aud[X].ac_len $0A4 Audio channel X length.
This register contains a count of the number of words to be sent
through the DMA channel for sound generation. You can set the
starting addres for these words in the register that is described
above.
------------------------------------------------------------------
aud[X].ac_per $0A6 Audio channel X sounding frequency.
In this register you specify how many bytes per second are used for
sound generation. Since the sound DMA channel is synchronised with
the screen DMA channel, only two bytes per raster row can be made
audible. Theoretically, it is possible to make two (bytes) *
262.5 (raster rows) * 59.94 (screen displayed) = 31468.5 bytes
per second audible in PAL systems.
Because the DMA controller is responsible for other tasks besides
sound generation, it is only possible to sample 28867 bytes per
second.
This means that you could send one byte through the sound channel
in 1/28867 seconds = 34.642 microseconds. This provides the value
for this register: ac_per = 34.642 microseconds/Num_Microseconds
for one scan.
PAGE 559
-----------------------------------------------------------------------------
The hardware determines the limits for the scan per timing cycle.
Since the timing cycle is 280 nanoseconds or 0.28 microseconds,
a value of 123 (34.643 microseconds / 280 nanoseconds) is the
smallest possible value for this register. If you select a smaller
value the DMA channel can no longer function properly.
------------------------------------------------------------------
aud[X].ac_vol $0A8 Audio channel X volume.
Use this register to set your audio volume level for channel X.
Only the lower five bits are essential to volume.
The maximium volume level is 64; setting this register to zero
turns off your sound.
------------------------------------------------------------------
aud[X].ac_dat $0AA Audio channel X data.
This register is the audio DMA data buffer. If contains two bytes
in two compliments which are sequentially sent through the sound
hardware.
The DMA controller automatically writes the values read from
ac_ptr into these registers. To create sound without using the DMA
channels, you can write directly to these register by using the
68000. When doing this, make sure that you dont enable DMA access
at the same time because this will disturb the interrupt timing.
------------------------------------------------------------------
bltXpt $050 Blitter pointer.
This register pair pointer contains an 18 bit pointer to the DMA
data that the blitter will act upon. X represents a,b,c and d
which are the three sources (a,b,c) and the target (d) for the
blitter operation (Blits).
The data for a blit operation is read from bltapt, bltbpt and
bltcpt; it is operation on and stored at bltdpt.
When the blitter operation is complete, the pointer contains the
last data address (plus increment and modulo) for the data written
and read. To include the target (d) in the blit operation, one
of the sources (a,b or c) must contain the same address as the
target (d).
The blitter is not only responsible for blitting, but also for
drawing lines. Because this additional task is integrated into this
processor, it is easy to understand why the amiga can draw lines
so quickly.
PAGE 560
-----------------------------------------------------------------------------
How the bltapt, bltbpt, bltcpt and bltdpt registers affect line
drawing is not relevant here because the Draw() instruction was
designed for this function.
------------------------------------------------------------------
bltXmod $064 Blitter Modulo X
This register contains the modulo for the Blitter sources (a,b and
c) and the Blitter target (d). Since it is possible to use
different sized bitmaps, which we can blit between, we must know
the size of each bitmap that the Blitter will work with. A blit
operation is not limited only to one bitmap.
You must provide the width for each bitmap, that is used for the
blit operation as the modulo parameter. This is how a rectangle to
be blitted is transferred from one bitmap to the other.
Remember that the blitter can only operate on data by bitplane.
This means that when you control the blitter yourself and blit
a rectangle from one bitmap to another, you must provide, with
bltxpt, the rectangle position for each bitplane. The modulo is
read last and added to the written word to locate the start of the
next row.
Commodore has provided some bery powerful instructions that
fully use the blitter (BltBitMap(), BltTemplate(), ScrollRaster())
As with drawing lines, the modulo registers also have a specific
purpose. However, as we said earlier, the Draw() function does all
the work for you.
------------------------------------------------------------------
bltafwm $044 Blitter First word mask for Source A
bltalwm $046 Blitter Last word mask for Source A
In order to blit a rectangle that starts in the middle of a word
instead of at a word address, the first and last word of a row to
be blitted (the source A) is ANDed with a specific value. The
remaining bits are changed, reworked and written into the row.
-----------------------------------------------------------------
bltXdat $074 Blitter X data register.
Similar to sound generation, the individual words from source a,b
and c are read here before they are logically merged. This action
is performed by the DMA channel. After the blit of these three
words, the resulting word is written, by the DMA channel to the
bltdat and then to the target. The entire blit operation is
reduced to operating on three words.
PAGE 561
-----------------------------------------------------------------------------
bltcon0 $040 Blitter control register 0
bltcon1 $042 Blitter control register 1
These two registers are used to control the Blitter operation (blits).
There are two modes, Area and Line, that are selected through bit 0
of BLTCON1:
The Area Mode bltcon0
Bits 15-12 ASH3-0:
If you have ever moved a bob by pixels, you probably wondered
how this was possible since the blitter can only access word
addresses.
By using the bits ASH3-0, you can select how many pixels the data
from source A is rotated before being written to the target.
Bits 11-8 USEx:
These bits determine which source the blitter can access. If you
have only two sources, it would be a waste of time to access all
three possible sources. Besides, there wouldnt be any data in
source C.
With the USEx bits you can select your source; X stands for the
a,b,c and d. Make sure you activate the target, otherwise the
data will have no place to go.
Bits 7-0 LF7-0:
These bits determine the type of logic operation that will be
performed, by the blitter, on your source data. The bit patterns
written here are also called minterms, which you learned about in
connection with the Blitter instructions. Only two sources are
considered, b and c.
However, there are three sources you can use. What happens with
each source is determined by the individual bits LF7-0.
PAGE 562
-----------------------------------------------------------------------------
Bits:LF 7 6 5 4 3 2 1 0
_ _ __ _ _ _ __ ___
Minterm: ABC ABC ABC ABC ABC ABC ABC ABC
ABC:D = A and B and C
_
ABC:D = A and B and !C
_
ABC:D = A and !B and C
__
ABC:D = A and !B and !C
_
ABC:D = !A and B and C
.
.
.
The area mode bltcon1 has the following bit pattern in area mode:
Bits 15-12 BSH3-0:
These bits have the same meaning as ASH3-0 with bltcon0, except
that source B is shifted.
Bits 11-5: Commodore has not assigned a function to these bits yet.
Bits 4, 3 EFE/IFE:
Earlier we mentioned that the blitter is capable of performing our
fills. Thses two bits determine the fill mode for an area already
set for the Blitter. When bit EFE is set (Exclusive Fill Enable),
the area outline to the left of the filled area is erased after
the fill operation. If EFE is unset and IFE is set (Inclusive
Fill Enable), the area is filled normally. To achieve a clean
fill, the area border must fulfill specific requirements: Only
one single pixel may be set on each horizontal line (see SING).
Bit 2 FCI:
This bit is the starting value for the fill "flip-flop". Just
like an electronic flip flop, the Blitter also switches status
back and forth while filling. Whenever a specific external event
occurs, the Blitter switches and then keeps this status until a
new event of the same type happens.
An event for the Blitter looks like this: the Blitter finds a set
bit in a bitplane row and the status of the Fill Flip Flop is
toggled. All the following bits that are clear are written with the
value of FCI. You can also determine whether an area is filled
inside or outside.
Bit 1 DESC:
This bit determines the direction in which the Blitter works in the
specified data area (source a,b,c and d). When DESC is set, the
direction is downward from the provided address. When DESC is clear,
the Blitter works upwards. This bit is very important when target
and source overlap.
PAGE 563
-----------------------------------------------------------------------------
Bit 0 LINE:
(=0) When this bit is clear the Blitter operates in Area mode.
When drawing lines all of these bits have new meanings:
BLTCON0
--------
Bits 15-12 START3-0:
These bits set the code for the horizontal position of the first
pixel of the line.
The exact format used by Commodore for START3-0 was not available
when this book was written. For this reason we have provided only
limited information on drawing lines with the blitter.
Bits 11, 10, 9, 8 %1011:
These bits must be initialised to a value of %1011 (only Commodore
knows why).
Bits 7-0 LF7-0:
When drawing patterned lines, the Blitter sources are used in some
capacity. Again, only Commodore has the complete information.
BLTCON1
-------
Bits 15-12 TEXTURE3-0:
A value (0-15) in these four bits sets the starting bit position
for the pattern in a line.
Bits 11-7 %00000
All these bits be must be cleared.
Bit 6 SIGN:
This bit must contain the sign for the rise of the line.
Bit 5 %0
This bit is reserved for a new mode and should be kept clear for
upward compatibility with other programs and machines like the
2000.
Bits 4-2 SUD, SUL, AUL:
These bits are used for super fast line drawing. This super fast
method is based on the symmetric characters of a line that the
blitter uses. You control the drawing of a line with these three
bits named "sometimes up or down", "sometimes up or left" and
"always up or left". Whether they can be set by you or only by the
blitter is somethinf we were unable to find out.
PAGE 564
-----------------------------------------------------------------------------
Bit 1 SING:
If this bit is set, each line is displayed by only one pixel in
each bitplane row. This is important for the blitter when filling
areas.
Bit 0 LINE:
(=1) This bit determines the blitter mode. When set the blitter
operates in line mode.
----------------------------------------------------------------
bltsize $058 Blitter: start and size (width, height)
This register contains the height and width of the Blitter's operating area.
All operations occur in this defined window. The starting address is set in
bltXpt and the operations are determined by bltcon0/1 and other registers.
When you access these registers (through the Copper or 68000), Whether
reading or writing, the Blitter immediately executes the blit.
This is why you should first initialise all other registers (BLTAF/:WM,
BLTxDAT,BLTCON0/1, BLTxMOD etc..) and then perform the write. This start
effect also applies to drawing lines.
Bits 15-6 H9 - H0
These ten bits determine the number of rows for the Blitter's
operating area and can contain a value between 0 and 1024.
Bits 5-0 W5-WO:
These bits determine the width, in words (64 * 16 bits = 1024), of
the Blitter's operation area. Theoretically the Blitter can operate
with a memory area of 1024 x 1024 pixels (a superbitmap).
This register also has a different effect when it used for line
drawing. BLTSIZE controls the Iine length and accessing this
register tells the Blitter to start drawing the line. The H9-H0
bits control the line length (up to 1024 pixels) and bits W5-W0
must be initialised to %00010.
Since we could not provide complete information about the Blitter
registers, we recommend that you utilise the libraries and BASIC
instructions.
--------------------------------------------
bplpt[6] $0E0 Bit-plane X pointer
This register pair (see ac_ptr) contains the 18 bit pointer to the
starting address for bit-plane x (x=1,2,3,4,5,6) DMA data. This
register, which must be initialised by the 68000 or the Copper
after every raster return, is responsible for making your graphics
visible.
PAGE 565
-----------------------------------------------------------------------------
Since there are a few more than the 480 visible rows on your screen (
with interlace and overscan), a scrolling effect can be achieved
through this register. However, instead of manipulating the hardware
yourself, you can use the RxOffset and RyOffset variables in the
RasInfo structure and the library instruction scrollVPort() to
scroll an entire bit-map in a ViewPort.
--------------------------------------------
bpldat[6] $110 Bit-plane X data
As with DMA operations, registers are also required for temporary
data storage. After the DMA controller stores data in these six
registers, they are used by the video hardware (Videoshifter).
--------------------------------------------
bpl1mod $108 Bit-plane modulo (odd planes)
bpl2mod $10A Bit-plane modulo (even planes)
These registers contain the modulo (the width) for the even (2,4,6)
and odd (1,3,5) bit-planes (seeDBBLPF and bplXmod). The modulos are
essential for a correct display.
--------------------------------------------
bplcon0 $100 Bit-plane control register
bplconl $102 Bit-plane control register
bplcon2 $1-4 Bit-plane control register
You can control the video shifter like the Blitter. Use these three
registers, which are the core of the entire graphic display.
bplcon0
-------
Bit 15 HIRES:
If this bit is set, the display is in high resolution mode (640 *
... pixels). In this mode (4 bit-planes), you can only use 16 colors,
which are determined by the lower 15 color registers (see COLORxx).
Bits 14-12 BPU2-0:
These bits determine how many bit-planes you are using (0-6). Six
bit-planes are only required for dual playfields (DBLPF),
hold-and-modify (HAM), and extra halfbrite modes. The number of
bit-planes determines the number of possible colors: colors = 2BPU.
So, it is possible to use five bit-planes and 32 colors without
hold-and-modify. Setting all of these bits to zero displays only
the background color (COLOR00).
Bit 11 HAM:
This bit switches on the hold-and-modify mode.
Bit 10 DBLPF:
This bit switches on the dual playficld mode.
PAGE 566
-----------------------------------------------------------------------------
Bit 9 COLOR:
Setting this bit sets your display output for a composite monitor.
This means that the normal three color (RGB) is no longer used, and
a single output for composite is activated.
All older model monitors are of the composite type. Since the colors
must be separated from the single input signal, the picture on a
composite isn't as good as one that uses RGB.
Bit 8 GENLOCK:
With a genlock interface it is possible to display, instead of the
background color, the output from a video recorder, videocamera or
laser disk. This enables you to overlay the background video with
your own title and graphics. In order to use such an interface, your
software has to set this bit.
Bit 7 EXTRA_HALFBRITE:
This bit switches on the halfbrite mode.
Bits 6-4: Not used
Bit 3 LPEN:
In order to use a light pen, this bit must be set. This tells the
Amiga to test for the light pen position through the control port.
Light pens can only be used with control port one (see VPOSR).
Bit 2 LACE:
This bit switches on the interlaced mode, which doubles the vertical
display resolution from 200 rows to 400 rows. With interlace the
screen is actually displayed twice. The first display is the even
numbered rows and the second display is the odd numbered rows of
the bit-map.
Bit 1 ERSY:
This bit enables external synchronization of the electronic scanning
beam.
Bit 0: Not used
bplcon1
-------
Bits 15-8: Not used
Bits 7-4 PF2H3-0,
Bits 3-0 PFlH3-0:
These bits set the number of pixels that a playfield is horizontally
scrolled when displayed. You can use any value between zero and 15
pixels.
PAGE 567
-----------------------------------------------------------------------------
By using bplpt[x], you can achieve word type scrolling. These bits
are also available for finer scrolling.
However, you can also use ScrollVPort() and RasInfo.RxOffset. So this
register is not too important.
bplcon2
-------
Bits 15-7: Not used
Bit 6 PFsPRI:
Setting this bit gives playfield 2 complete video priority over
playfield 1. Clearing this bit puts playfield 1 in the foreground
(PFBA).
Bit 503 PF2P2-0,
Bits 2-0 PF1P2-0:
The bit combination in these bits set the video priorities between
playfield 1 and the sprites and between playfield 2 and the sprites:
Value Priority
000 PF1/2 > SP0/1 > SP2/3 > SP4/5 > SP6/7
001 SP0/1 > PF1/2 > SP2/3 > SP4/5 > SP6/7
010 SP0/1 > SP2/3 > PF1/2 > SP4/5 > SP6/7
011 SP0/1 > SP2/3 > SP4/5 > PF1/2 > SP6/7
100 SP0/1 > SP2/3 > SP4/5 > SP6/7 > PF1/2
('>' means has Priority over)
You don't have to set the video priority for sprites because the
hardware automatically knows that the lower numbered sprites have
priority over the higher numbered sprites. The mouse pointer has
sprite number zero with priority over all the other sprites.
When different ViewPorts are displayed, These registers are usually
changed many times for each display. If there is only one ViewPort,
the Copper changes these every sixtieth of a second.
--------------------------------------------
clxcon $098 Collision control
This register determines what type of collisions (between
bit-planes, sprites and bit-planes, or sprites and sprites) are
looked for by your Amiga. Through the value stored in clxdat, you
can discover which objects have collided. The individual bits for
clxcon have the following functions:
Bits 15-12 ENSP7, 5, 3, 1:
Setting one of these bits allows you to check the odd numbered
sprites (7, 5, 3, 1) for collision control. The even numbered
sprits (0, 2, 4, 6) are always checked for collisions, but the odd
ones aren't
PAGE 568
-----------------------------------------------------------------------------
However, unless you are using attached sprites that are at the same position,
you cannot determine through CLxDAT whether an odd or even numbered sprite
has collided with an object.
Bits 11-6 ENBPx:
Use these bits to set which bit-planes (x = 6-1) are tested for
collisions. Clearing these bits always indicates one bit-plane
collision.
Bits 5-0 MVBP6-1:
These bits determine whether bit-plane collisions with sprites are
registered by set or cleared bits. For example, only one bit-plane
collision is registered when a pixel is set in bit-plane 1 and
not registered for bit-plane 2 at the same position, etc. This
makes it possible to determine if a sprite has collided with a
specific colored pixel.
--------------------------------------------
clxdat $00E Collision data register
This register helps you to determine which collisions have occurred.
Bit 15 unused (usually = 1)
Bit 14 Sprite 4 (or 5) with sprite 6 (or 7)
Bit 13 Sprite 2 (or 3) with sprite 6 (or 7)
Bit 12 Sprite 2 (or 3) with sprite 4 (or 5)
Bit 11 Sprite 0 (or 1) with sprite 6 (or 7)
Bit 10 Sprite 0 (or 5) with sprite 4 (or 5)
Bit 9 Sprite 0 (or 1) with sprite 2 (or 3)
Bit 8 Playfield 2 with sprite 6 (or 7)
Bit 7 Playfield 2 with sprite 4 (or 5)
Bit 6 Playfield 2 with sprite 2 (or 3)
Bit 5 Playfield 2 with sprite 0 (or 1)
Bit 4 Playfield 1 with sprite 6 (or 7)
Bit 3 Playfield 1 with sprite 4 (or 5)
Bit 2 Playfield 1 with sprite 2 (or 3)
Bit 1 Playfield 1 with sprite 0 (or 1)
Bit 0 Playfield 1 with playfield 2
PIayfield 1 is the odd bit-planes (1, 3, 5) and playfield 2 the
even (2, 4, 6).
This register provides many possibilities for determining sprite
collisions. Since bit-plane collisions provide less information,
specific determinations are impossible.
Remember that sprite collisions are first registered when two pixels
overlap instead of when the edges collide.
PAGE 569
-----------------------------------------------------------------------------
Also, when you read this register, it is immediately cleared and not written
to again until the next raster scan (vertical blank).
--------------------------------------------
color[32] $180 Color register
There are 32 color registers ($180 - $1BE) that contain a 12 bit color code
for every color that exist in the bit-planes..
The color register that determines the color information for a specific pixel
is calculated by ORing - the value for all bit-planes for that pixel
position.
The color code is composed of 12 bits which makes 4096 different colors
possible. You can use a maximum of 32 of the 4096 colors for one screen
(hold-and-modify is an exception to this rule). Your pixel is then displayed
in the color calculated for its color register. Here is the bit pattern
used in all of the color registers:
Bits 15-12 Unused
Bits 14-8 Red 3-0 Red component of color
Bits 7-4 Green 3-0 Green component of color
Bits 3-0 Blue3-0 Blue component of color
The fourth bit determines the intensity of a color component (red, green,
blue). It is possible to create almost any color by mixing the three
different colors and their intensities (0 = dark, $0f = light).
--------------------------------------------
copcon $02E Copper control register
This register is a one bit register. Only bit one is used, all the other
bits are unused.
Some computer users refer to this register as the Copper danger bit.
Register zero (bltddat) to register 30 (strlong) are exempt from Copper
manipulation.
Usually, the Copper cannot access registers 31 (bltcon0) to 49 (dsksync).
Setting the danger bit allows you to use these registers. Any reset clears
this bit.
--------------------------------------------
copjump1 $088 (Strobe) Copper Newstart the first list.
copjump2 $08A (Strobe) Copper Newstart the second list.
By accessing these registers, either through the Copper or 68000, causes the
Copper to execute a Copper list. The starting list address should be in
cop1lc or cop2lc and the Copper-Program-Counter (PC) is directed to this
address.
PAGE 570
-----------------------------------------------------------------------------
The Copper list, whose start address is in cop1lc, is executed with each
raster scan (vertical blank).
For your own experiment with Copper list it is safer to use the user Copper
list. The entire display is controlled by the Copper and direct access can
cause serious problems unless you take control of the entire display.
--------------------------------------------
cop1lc $080/$082 Address of first Copper list.
cop2lc $080/$084 Address of second Copper list.
When you access registers copjmp1 or copjmp2, they contain the starting
addresses of Copper lists for execution.
The address of the hardware Copper list is loaded into these registers
through Loadview().Cop2lc is only used with interlace mode for the second
screen scan. After the first scan the second Copper list is started by the
first.
--------------------------------------------
copins $08C Copper instruction register
Like the DMA channcl, the Copper also uses a temporary buffer. Two 16 bit
instruction words are stored in this register and executed sequentially.
The first instruction word consists of one of the three possible Copper
instructions, the affccted hardware register and the position of the
electronic beam that will be waited for.
However, the three possible instructions, CMOVE(), CWAIT() and CEND() aren't
the only instructions you can use. The instructions Move, Wait and Skip are
also available.
The reason for this is that the CEND() instruction is actually a
subinstruction of CWAIT() and the Skip instruction wasn't considered useful
enough to be includcd in C.
MOVE and WIAT have the same meaning as CMOVE () and CWAIT ().
The skip instruction actually skips the following Copper instructions when
the electronic beam has reachcd the selected position.
A complete Copper instruction consists of two 16 bit words that are
loaded and executed sequentially in these registers.
Instruction: MOVE
1. Instruction Word
PAGE 571
-----------------------------------------------------------------------------
Bits 15-9 Unused
Bits 8-1 DA8-1:
DAx (Destination Address), which is used by the Move instruction,
selects the register the value of the second instruction will be
written. DA is specified as an offset from $DFF000 for the selected
hardware register.
Bit 0 0: This bit is used to identify a Copper move instruction. Move must
always be zero (The first bit of the second instruction word isn't
required for decoding this instruction).
2. Instruction Word
This word contains the 16 bit value that will be written to the register
seleclted by DA.
WAIT
----
1. Instruction Word
Bits 15-9 VP7-VP0:
VP (Vertical Position) contains the vertical (Y) position of the
electronic beam that will be waited for.
There are 262 different vertical beam positions that can be waited
for. Since VP has a data width of only eight bits, a small trick must
be used in order to access positions 256 through 262.
Usually, first you wait for the vertical position 255. Then you use a
second wait instruction for a position between zero and six.
Bits 8-1 HP8-HP1:
HP (horizontal position) contains the horizontal (X) position for the
electronic beam that will be waited for. It can contain a position
value betweenn zero and 226. Since the available data width is only
seven bits, the Copper can access only 113 positions. This limits
you to a pixel resolution of four with low-res (HIRES = 0) or eight
with hi-res (HIRES = 1).
It is possible for you to wait for every fourth pixel position.
However, this doesn't mean that you can change a register for every
four pixels. When you execute two moves, one after the other, there
is a gap of eight low-res pixels (with hi-res this value doubles).
Bit 0 1:
This bit and bit zero of the second instruction word are used to
identify the Copper instructions wait and Skip. When bit zero of the
first
PAGE 572
-----------------------------------------------------------------------------
word is clear, the Copper knows that it is working with a MOVE
instruction so it doesn't test the second instruction word.
When bit zero of the first word is set the Copper knows that it must
either wait or skip. Which action is performed is set by you in the
instruction word.
2. Instruction Word
Bit 15 BFD:
Setting this bit puts the wait instruction on hold until the Blitter
says "OK" (Blitter Finished Disable).
Bits 14-8 VE6-VEO:
VE (Vertical Comparison Enable) and HP (Horizontal Comparison Enable)
determine which bits are used for comparing the electronic beam
position.
Bits 7-1 HE-8-HE-2:
This bit has the same meaning for horizontal position as VE does for
vertical positioning.
Bit 0 %0:
The Copper recognises the WIAT instruction at this location.
SKIP
Except for the set or unset status of bit zero of the second
instruction word, the bit pattern of the instruction words for SKIP
and WAIT are very similar. The meaning of all the other bits is the
same.
--------------------------------------------
diwstrt $08E Display window start (top, left position)
diwstop $090 Display window stop (lower, right position)
Use these registers to set the actual display (ViewPort) size for
your screen. The values in these registers determine the upper left
corner and the lower right corner of the screen. Besides the
background color (in color[0]), nothing can be displayed outside
this screen.
These positions are specified in normal (not interlaced) raster row
and low resolution pixel values. You don't have to change these
values to use interlace or hi-res modes.
The bit pattern of these registers is as follows:
diwstrt
Bit Function
--------- ------------------------------------------------
15-8 VSTART vertical start position
7-0 HSTART horizontal start position
PAGE 573
-----------------------------------------------------------------------------
The starting position of your display is set in these two registers.
However, you cannot set the starting position of a ViewPort here.
Because of the eight bit data width of these registers, you can only
use horizontal and vertical starting and ending positions between
zero and 256 raster rows.
diwstop
Bit Function
15-8 VSTOP vertical start position
7-0 HSTOP horizontal start position
Diwstop also has the same eight bit pattern. In order to display a
window wider than 256 pixels, a value of $100 must be added to the
X end coordinate to maintain the actual end position.
Bit VSTOP7 is very important for calculating the actual vertical end
coordinate. The nonexistent VSTOP8 bit is actually the compliment
of VSTOP7. If VSTOP7 is cleared, VSTOP8 is set. When VSTOP7 is zero,
you simply add 256 to calculate the actual vertical end position.
lf VSTOP7 is set you can disregard VSTOP8 since it is zero and not
active in the calculation.
When writing to these registers, be aware of "Vertical Blank". The
top visible raster is not raster zero just as the first visible
column is not the first column raster wise.
The electronic beam needs some time to recover after reaching the
bottom screen border. This is similar to when the beam finishes
displaying a raster row.
Normal values for diwstrt and diwstop are:
diwstrt=$2c81
diwstop=$f4c1
This provides a screen window size of:
HSTOP+$100-HSTART = $c1-t$100-$81 = $140 = 320 Pixels
VSTOP+(VSTOP8 * $100)-VSTART = $F4( = %11110100)+(0*
$100) - $2c = 200 Normal-Raster rows
Also remember not to use a vertical starting value smaller than $20
Because, while creating the screen, the vertical blank needs an area
for the beam return. Otherwise you wouldn't see anything on the
screen. Because the electronic beam wasn't given enough recovery
time.
PAGE 574
-----------------------------------------------------------------------------
ddfstrt $092 Screen data fetch start
ddfstop $094 Screen data fetch stop
These two registers determine when to get the data from memory and
display it.
One timing cycle is used to display two pixels. To determine when to
start and stop displaying data, use the values from the diwstrt and
diwstop registers. Eventually you will add a small offset to these
values and then the desired values for ddfstrt and ddfstop will be
available.
The offset is different for lo-res and hi-res modes. For lo-res the
offset is 8.5, and for hiRES is 4.5.
Start position values are:
ddfstrt=($81/2-8.5)=$38
(Hi-res: ddfstrt = ($81/2 - 4.5) = $3C)
You calculate the value for ddfstop like this:
ddfstop = ddfstrt + (16/2 *(Number of words per line -1))
(low-resolution)
ddfstop = ddfstrt + (16/4 *(Number of words per line -2))
(high-resolution)
Again the number of displayed pixels (1 word = 16 pixels) is halved
and quartered. The quartered value for hi-res is natural because
hi-res displays twice as many pixels in the same amount of time.
You cannot select these values because they are limited from the
hardware side. DDFSTRT cannot be smaller than $18 and DDFSTOP cannot
be larger than $D8. These values permit a display of 376 pixels with
lo-res (752 with hi-res). By using a DDFSTRT value smaller than $38,
you can prevent the display of several sprites.
--------------------------------------------
dmacon $096 DMA control register (write)
dmaconr $002 DMA control register (read)
These registers are used by the DMA controller to manage the
information fed to it by the various processors.
With dmacon, set which DMA channel is open.
This is the bit pattern which is the same for both registers:
Bit 15 SET/CLR:
(see ADKCON)
PAGE 575
-----------------------------------------------------------------------------
Bit 14 BUSY:
This bit shows the blitter status. When the blitter is working this
bit is set.
Bit 13 BZERO:
This bit is set when all the result bits of a blit (screen area
copy etc...) were zero.
Bits 12,11: Unused.
Bit 10 BLTPR1:
This bit determines the priority between the Blitter and the 68000.
How the 14mhz clock frequency is divided between the two processors
is set here.
Bit 9 DMAEN:
When this bit is set, it is possible to activate all the DMA
channels. If this bit is clear the value of all the following
bits have no effect on the status of the DMA channels that they
activate. So, DMAEN is the controller of DMA activity.
Bit 8 BPLEN:
When this bit and DMAEN are set, the DMA channel for screen data
transfer from the bitplanes is activated.
Bit 7 COPEN:
This bit sets the Copper status. If it is set, the Copper can work
and if it is clear, the Copper is shut off.
Bit 6 BLTEN:
What applies to the Copper with COPEM applies here to the Blitter.
Bit 5 SPREN:
Setting this bit enables transfer of sprite data through the DMA
channels.
Bit 4 DSKEN:
This bit determines the status of the disk DMA channel. Clearing
this bit stops all data transfers between computer and floppy.
Bits 3-0 AUD3-0EN:
These bits determine the status for the sound DMA channels.
Clearing these bits prevents any sound activation through the DMA
channels.
PAGE 576
-----------------------------------------------------------------------------
dskpt $020 Disk pointer
This register pair (also an 18 bit pointer) determines the data read
storage address for the disk DMA data that will will be written to
disk.
--------------------------------------------
dsklen $024 Disk data length
Thiss register contains the word count of the words to be sent or
received through the disk DMA channel. One bit of this register
determines the data direction (RAM -> disk or disk -> RAM). Another
bit determines whether access to the DMA channel is possible.
Accessing this register executes the data transfer. The register must
be written to twice with the same data. When all data has been
transferred a "Disk Block Interrupt" (see INTREQ) is sent that stops
the data transfer.
Just setting the DMA register isn't the only requirement for
executing a complete disk operation such as loading a program.
You must also set a pair of I/O registers for the CIAs. However, we
won't discuss these registers Because they belong in a different book,
such as "Amiga System Programmers Guide".
Bit 15 DMAEN:
Setting this bit enables the data transfer through the DMA channel.
Bit 14 WRITE:
This bit determines the write/read direction. When set, the data is
read from RAM through the DAM channel and written to disk. When
clear, the data is read from disk.
Bits 13-0 LENGTH:
These bits contain the number of words that will be read or written.
--------------------------------------------
dskdat $026 Disk DMA data (write)
dskdatr $008 Disk DMA data (read)
These registers contain the data that is either read or written
through the disk DMA channel.
You should remember that the dskdatr register is protected from
Copper access.
--------------------------------------------
dskbytr $01A Disk databyte and status
This register is a data buffer that is directly linked to The disk
microprocessor. From this register, data is sent to the DMA
controller
PAGE 577
-----------------------------------------------------------------------------
or received from the disk controller. There are also a few status
bits in this register.
Bit 15 DSKBYT:
When bytes are read from disk, this bit is set as soon as the
byte has been completely read.
Bit 14 DMAON:
This bit, which has the same value as DMAEN in dislen, is
ANDED with bit DMAEN from dmacon. When the result is a one, data
transfer from the disk device is possible.
Bit 13 DISKWRITE:
This bit has the same value and meaning as WRITE in dsklen.
Bit 12 WOREQUAL:
This bit is set only When the dsksync register byte data will be,
synchronizcd with the word data.
Bits 11-8: Unused
Bits 7-0: These bits contain the data byte.
--------------------------------------------
dsksync $07E Disk synchronisation register
This register contains the synchronize code for disk operations.
--------------------------------------------
intreq $09C Interrupt request bits (write)
intreqr $01E Interrupt request bits (read)
intena $09A Interrupt enable bits (write)
intenar $01C Interrupt enable bits (read)
These are the interrupt requests, interrupt enable or mask bits that
determine which interrupts (cyclic breaks) are allowed.
This is where you can decide between request and enabling.
Interrupts can only occur When the corresponding enable bits are
set.
All four registers have the same bit pattern. The request and enable
registers are included twice, once for writing and again for reading.
Here is the bit pattern:
Bit 15 SET/CLR:
(See ADKCON)
Bit 14 INTEN (Master Interrupt enable):
When this bit is clear all interrupts for the following bits are
disabled.
PAGE 578
-----------------------------------------------------------------------------
Bit 13 EXTER:
This bit is used to generate an external interrupt through CIAB
(level 6).
Bit 12 DSKSYN:
This interrupt is executed when data is synchronized with the
DSKSYNC register (level 5).
Bit 11 RBF (receive buffer full):
This is where the interrupt for the serial port is tested. It is
executed when the serial input buffer is full and can be read by the
user level 5).
Bits 10-7 AUD3-0:
An interrupt is executed when sound data will be processed through
the DMA channel. In manual mode this interrupt is executed when the
audio data registers are ready to operate on new data (level 4).
Bit 6 BLIT (blitter finished):
This bit is set When the Blitter has completed its work (level 3).
Bit 5 VERTB:
An interrupt routine, which resets many pointers and executes other
system tasks, is performed for every raster return.
Bit 4 COPPER:
COPPER indicates that a Copper interrupt will be executed. Just as
it can change almost any register, the Copper can change any of
these these bits. After the entire screen has been displayed and
the electronic beam reached the DIWSTOP position, the Copper
interrupt occurs. This enables the 68000 to process special tasks
during the raster return.
Bit 3 PORTS:
PORTS indicates an interrupt that is executed during the low
processor cycle INT2 (level 2).
Bit 2 SOFT:
This bit is reserved for software interrupts.
Bit 1 DSKBLK (Disk block finished):
DSKBLK indicates that a dats transfer through the disk DMA channel
is complete (level 1).
Bit 0 TBE (transmit buffer empty):
TBE indicates that the UART (Universal Asynchronous
Receiver/Transmitter) output buffer can receive data and you can
write into this buffer (level 1).
PAGE 579
-----------------------------------------------------------------------------
Usually by setting the processor lines INT0, INT1 and INT2 low, there
could be seven different interrupts. These would only be system
interrups.
However, the Amiga further specifies these system interrupts within
the intterrupt handler, which produces more than seven possible
interrupt levels.
--------------------------------------------
joy0dat $00A Joystic/mouse 1 (left port)
joy1dat $00C Joystic/mouse 2 (right port)
These two registers provide information for the status of the entry
device (joystick, mouse, lightpen, potentiometer, etc.) that is
connected to the related control port. The following applies to the
specific entry devices:
Mouse or trackball:
For these devices the register contains a value that is proportional
to the actual movement. This movement is split between the
horizontal (x direction) and vertical (Y direction) in the
register. Bits 15-8 contain the vertical movement and bits 7-0
contain the horizontal movement. These register values come from the
rotation of the ball, which turns the raster sliders between
light sensors.
Breaking the light sensor contact and then making contact again
represents one impulse. The Amiga mouse sends 200 impulses per inch.
These two bytes are then counters of the light impulse breaks.
The counters increase when you move the mouse left or down and
decrease when you move the mouse right or up. To determine the
movement direction, compare the difference of the current value to
the new value. When the difference is negative, the mouse is moving
down or right.
In order to make the mouse position available to Intuition, this
register is read and cleared after each vertical blank.
The left mouse button is read through bit six of the CIAA register
$BFE001. The right mouse button is read from the pot0dat register.
The Joystick:
Testing for joystick positions is easier than testing mouse
movements. When bits one or nine for joyO/1dat are set, the
joystick has been moved left or right. To check for up and down
movement, you must XOR bit nine and eight with bits one and zero.
The fire button for a joystick in the left port is tested the same
way as the left mouse button. The fire button for the right joystick
is read from bit five of register $BFE001.
PAGE 580
-----------------------------------------------------------------------------
The typical programmer shouldn't try direct reading of the joystick
and mouse because the system software handles this for you. However,
when the system does not satisfy your control requirement, you could
experiment with the information presented here.
--------------------------------------------
joytest $036 Write all mouse counters
The values written to this register are transferred to both
joy0dat and joy1dat registers. This allows you to initialise both of
them at the same time.
pot0dat $012 Pot counter left (vert, horiz).
pot1dat $014 Pot counter right (vert, horiz).
Like most computers, paddles can also be used with the Amiga.
Those are simply potentiometers that are read every sixtieth of a
second for their current position.
When you set the starbit in potgo, electricity is sent through the
resistor via a capacitor. The capacitor loads for a short time (about
eight raster rows) and then unloads. Then the actual Load of the
capacitor is compared to a standard value.
If the current load is higher than the standard, a previously cleared
counter is incremented. When the load is smaller, the compare
operation is cancelled and the proportional resistance value is
stored in this register. You can connect two of these paddles to
each control port which is allowed for proportional joysticks.
Test the paddle fire buttons as usual through the left and right
joystick positions. Here is the bit pattern for these registers:
Bits 15-8 Y7-YO:
Potentiometer position of pot at pin 9
Bits 7-0 X7-XO:
Potentiometer position of pot at pin 5
The electrical resistance, which must be al least 470K Ohms, plus
or minus ten percent is sent through pin seven (+5V, 125mA).
--------------------------------------------
potinp $034 Pot port data write and start
potgo $016 Pot port data read
The control ports also function as 4 bit bidirectional I/O ports.
These registers are used to control them:
Bit 15 OUTRY (right Port, Pin9)
Bit 14 DATRY
PAGE 581
-----------------------------------------------------------------------------
Bit 13 RX (right Port, Pin 5)
Bit 12 DATRX
Bit 11 OUTLR (left Port, Pin 9)
Bit 10 DATLR
Bit 9 OUTLX (left Port, Pin 5)
Bit 8 DATLX
The OUTxx bits set the line status. When these bits are set,
data DATxx is output. If these bits are cleared, data DATxx is read.
Bits 7-0 0: Reserved
Bit 0 START:
When this bit is set (potgo), the capacitors are loaded and the
counters start counting.
--------------------------------------------
refptr $028 Write refresh pointer
This pointer is used as a RAM refresh pointer. Instead of constantly
receiving electricity, the memory bits are loaded every 280
nanoseconds (= one memory cycle). Therefore, their old value is
constantly kept fresh. Because of this technique, it is possible to
use five volt power for most ICs.
These registers should never be accessed by the 68000 or Copper
because this can confuse the intemal timing, which can cause loss of
data.
--------------------------------------------
serdat $030 Serial port: data and stop bits (write)
The data that is writtcn to this register is further written to a
shifter, which transfers a byte, bit by bit, through the serial bus.
When this buffcr can receive data, it sends a TBE (Transmit Buffer
Empty) interrupt (see INTREQ). Depending on the setting of the LONG
bit in the serper register, either eight or nine data bits are used.
Bits 15-10: 0
Bit 9: Stopbit
Bits 8-0: Databits
--------------------------------------------
serdatr $018 Serial port: dats and status (read)
This register, which is the opposite of serdat, contains the data
bits receivcd from the buffer through the shifter. Various interrupt
request bits (INTREQ) are also in this register.
PAGE 582
-----------------------------------------------------------------------------
Bit 15 OVERRUN:
This bit is set when there is an input buffer overflow. Clearing RBF
in INTREQ clears this bit.
Bit 14 RBF:
Bit 13 TBE:
Sec INTREQ
Bit 12 TSRE:
This bit is set when the shifter register is empty.
Bit 11 RXD:
The RXD processor pin receives data directly from the UART. This bit
can be tested directly from the 68000.
Bit 10: 0
Bit 9: Stopbit
Bit 8: Stopbit or D8
Bits 7-0 D7-D0:
--------------------------------------------
serper $032 Scrial port: rate and control
With this register you set the word data width (8 or 9 bits), which
the serial port will send or receive. The data transfer speed is
also set here.
Bit 15 LONG:
Setting this bit makes your data word nine bits wide.
Bits 14-0 RATE:
Thesc bits specify the speed for sending or receiving one bit.
To calculatc the time, use the following formula:
(value of the lower 14 bits + 1) * 2794 microscconds.
--------------------------------------------
sprpt[8] $120 Sprite x Pointer
This register pair contains the starting data address for every
sprite (x = 0, 1, 2, 3, 4, 5, 6, 7). In order to use sprites, this
register must be reset by the Copper or 68000 after every raster
return. To display sprites, the DMA channel (dmacon/SPREN) must also
be active.
PAGE 583
-----------------------------------------------------------------------------
spr[8].pos $140 Sprite X vertical & horizontal start position
spr[8].ctl $142 Sprite X vertical stop position
These registers work together to control the size, position and other
functions connected wilh hardware sprites. They are usually loaded
by the DMA conlrollcr durring the horizontal raster beam return.
The positions are again specified in raster rows or normal pixels.
pos
---
Bits 15-8 SV7-SV0,
Bits 7-0 SH8-S8H1:
SV7=SV0 sets the vertical (Y direction) start position of sprite x.
SH7=SH0 contains the horizontal (X direction) start position of
sprite x. There are only eight bits available for each position
coordinate. So spr[x].ctl contains the high value bit SV8 and the
SH0 contains the low value bit. This allows position values between
zero and 512 in both horizontal and vertical directions. The movement
of sprites is only possible in steps of low-res pixels and in normal
raster rows.
ctl
---
Bits 15-8 EV7-EV0:
These bits contain the vertical (Y) end position of sprite x.
This clearly reveals that sprites can have any desired height
(sprites are always 16 pixels wide). Remember that the highesy bit
(EV8) is bit one.
Bit 7 ATT:
Setting this bit selects paired sprites (0/1, 2/3, 4/5, 6/7 ) that
provide 15 colors per sprite instead of only three. Each sprite in a
pair can be movcd independantly. The 15 color bit pattern is
visible only When the sprites overlap.
Bits 6-4: Unused
Bit 2 SV8:
High value bit for SV7-SV0 in spr[x].pos
Bit 1 EV8: see EV7-EV0
Bit 0 SHO:
High value bit for SH7-SH0 in spr[x].Pos
--------------------------------------------
spr[8].dataa $144 Sprite X Image data register A
spr[8].datab $146 Sprite X Image data register B
These registers contain the rows of a sprite that will be displayed. dataa
contains the first word and datab contains the second word of any sprite.
When dataa is written into the register, it is compared
PAGE 584
-----------------------------------------------------------------------------
with the actual raster position in SH8-SH0. When both values are the same,
the sprite row is displayed.
Changing spr[x].ctl affects this comparison. The beam position is compared
only after dataa is accessed and eventually the sprite is displayed.
--------------------------------------------
strequ $038 Strobe for horiz. synchronisation with VB and EQU
strvbl $03A Strobe for horiz. synchronisation with VB
strhor $03C Strobe for horiz. synchronisation
strlong $03E Strobe for identification of a long horizonal.
These registers are used internally by the video shifter.
Unfortunately, we are unable to provide more detailed information
about them. However, the typical programmer really doesn't need
these registers.
--------------------------------------------
vposr $004 Highest value vertical positions bit (read)
vposw $004 Highest value vertical positions bit (write)
To synchronize actions of the 68000 with the electronic scanning
beam, these registers are used. So, the 68000 can wait for a
specific Y coordinate of the electronic beam and then take whatever
action is required by the Program (see WaitTOF).
These registers only contain the highest value bit for the vertical
position and an interlaced flag.
Bit 15 LOF:
This bit indicates whether or not interlace is switched on.
Bits 14-0: Unused
Bit 0 V8:
This is the highest value bit for the vertical electronic beam
position. You can also test for rows higher than 256
(313 for PAL and 262 for NTSC).
------------------------------------------------------------------
vhposr $006 vertical and horizontal electronic beamposition (read)
vhposw $02C Vertical and horizontal electronic beamposition (write)
These registers are used to read the current beam position or to set
(write) a new position, which is sometimes necessary when performing
tests. Usually these registers aren't used except for diagnostic
purposes.
The bit pattern is as follows:
PAGE 585
-----------------------------------------------------------------------------
Bits 15-8 V7-V0:
These bits contain the lowest bit values for the vertical beam
position. This high bit is stored in VPOSR.
Bits 7-0 H8-H1:
These bits contain the actual horizontal position of the beam. The
resolution value consists of 1/160 of the screen width.
PAGE 586
-----------------------------------------------------------------------------
The following register list is in offset address order (please remember the
offset from $DFF000):
Nr. Name Adress
------- -------------- ----------------
000 bltddat $000
001 dmaconr $002
002 vposr $004
003 vhposr $006
004 dskdatr $008
005 joy0dat $00a
006 joy1dat $00c
007 clxdat $00e
008 adconr $010
009 pot0dat $012
010 pot1dat $014
011 potinp $016
012 serdatr $018
013 dskbytr $01a
014 intenar $01c
015 intreqr $01e
016 dskpt $020
017 dsklen $024
018 dskdat $026
019 reftpr $028
020 vposw $02a
021 vhposw $02c
022 copcon $02e
023 serdat $030
024 serper $032
025 potgo $034
026 joytest $036
027 strequ $038
028 strvbl $03a
029 strhor $03c
030 strlong $03e
031 bltcon0 $040
032 bltcon1 $042
033 bltafwm $044
034 bltalwm $046
035 bltcpt $048
036 bltbpt $04c
037 bltapt $050
038 bltdpt $054
039 bltsize $058
-- $05a
-- $05c
PAGE 587
-----------------------------------------------------------------------------
Nr. Name Address
------- ------------- ----------------------------
-- $05e
040 bltcmod $060
041 bltbmod $062
042 bltamod $064
044 bltdmod $066
-- $068
-- $06a
-- $06c
-- $06e
045 bltcdat $070
046 bltbdat $072
048 bladat $074
-- $076
-- $078
-- $07a
-- $07c
049 dsksync $07e
050 cop1lc $080
051 cop2lc $084
052 copjmpl $088
053 copjmp2 $08a
054 copins $08c
055 diwstrt $08e
056 diwstop $090
057 ddfstrt $092
058 ddfstop $094
059 dmacon $096
060 clxcon $098
061 intena $09a
062 intreq $09c
063 adkcon $09e
aud[0]
064 ac_ptr $0a0
065 ac_len $0a4
066 ac_per $0a6
067 ac_vol $0a8
068 ac_dat $0aa
-- $0ac
-- $0ae
PAGE 588
-----------------------------------------------------------------------------
Nr. Name Address
------- -------------- ---------------------------
aud[l]
069 ac_ptr $0b0
070 ac_len $0b4
071 ac_per $0b6
072 ac_vol $0b8
073 ac_dat $0ba
-- $0bc
-- $0be
aud[2]
074 ac_ptr $0c0
075 ac_len $0c4
076 ac_per $0c6
077 ac_vol $0c8
078 ac_dat $0ca
-- $0cc
-- $0ce
aud[3]
079 ac_ptr $0d0
080 ac_len $0d4
081 ac_per $0d6
082 ac_vol $0d8
083 ac_dat $Oda
-- $0dc
-- $0de
084 bltpt[0] $0e0
085 bltpt[1] $0e4
086 bltpt[2] $0e8
087 bltpt[3] $0ec
088 bltpt[4] $0f0
089 bllpt[5] $0f4
--- $0f8
-- $0fa
-- $0fc
-- $0fe
090 bplcon0 $100
091 bplcon1 $102
092 bplcon2 $104
-- $106
093 bpl1mod $108
PAGE 589
-----------------------------------------------------------------------------
Nr. Name Address
------- -------------- -------------------------
094 bpl2mod $10a
-- $10c
-- $10e
095 bpl1dat $110
096 bpl2dat $112
097 bpl3dat $114
098 bpl4dat $116
099 bpl5dat $118
100 bpl6dat $11a
-- $11c
-- $11e
101 sprpt[0] $120
102 sprpt[1] $124
103 sprpt[2] $128
104 sprpt[3] $12e
105 sprpt[4] $130
106 sprpt[5] $134
107 sprpt[6] $138
108 sprpt[7] $13c
spr[0]
109 pos $140
110 ctl $142
111 dataa $144
112 datab $146
spr[1]
113 pos $148
114 cd $14a
IIS dataa $14c
116 datab $14e
spr[2]
117 pos $150
118 cd $152
119 dataa $154
120 datab $156
PAGE 590
-----------------------------------------------------------------------------
Nr. Name Address
------- -------------- ------------------------------
spr[3]
121 pos $158
122 ctl $15a
123 dataa $l5c
12A datab $15e
spr[4]
125 pos $160
126 ctl $162
127 dataa $164
128 datab $166
spr[5]
129 pos $168
130 cd $16a
131 dataa $16c
132 datab $16e
spr[6]
133 pos $170
134 ctl $172
135 dataa $174
136 datab $176
spr[7]
137 pos $178
138 cd $17a
139 dataa $17c
140 datab $17c
141 color00 $180
142 color01 $182
143 color02 $184
144 color03 $186
145 color04 $188
146 color05 $18a
147 color06 $18c
148 color07 $18e
149 color08 $190
150 color09 $192
PAGE 591
-----------------------------------------------------------------------------
Nr. Name Address
------- -------------- ------------------
151 color10 $194
152 color11 $196
153 color12 $198
154 color13 $19a
155 color14 $19c
156 color15 $19e
157 colorl6 $1a0
158 colorl7 $1a2
159 colorl8 $1a4
160 colorl9 $1a6
161 color20 $1a8
162 color21 $1aa
163 color22 $1ac
164 color23 $1ae
165 color24 $1b0
166 color25 $1b2
167 color26 $1b4
168 color27 $1b6
169 color28 $1b8
170 color29 $1ba
171 color30 $1be
172 color31 $1be
xxx NO-OP $1fe
PAGE 592
--------------------------------------------------------------------------
INDEX
------
3-D effects 39 AnimOb.AnY 482
1024*1024 paint program 293 AnimOb.HeadComp 481
AnimOb.PrevOb 483
AbortDoubleBuffer 180 AnimOb.XAccel 482
Absolute address 9 AnimOb.XVel 482
absolute coordinades 9 AnimOb.YAccel 482
access counter 216 AnimOb.YVel 482
action-verbs 51 AnimObs 479, 484
activity menu 1 5 AnimORoutine 483
AddAnimOb 483, 527 AREA 31
AddBob (&Bob, &RastPort) 527 Area... functions 356
AddFont (&Textfont) 527 AreaDraw (&RastPort, x, y) 528
Addressing 8 AreaEllipse 529
AddVSprite (&VSprite, Rastport) 528 AreaEnd (&RastPort) 529
AddVSpri@ 455 AREAFILL 31, 32, 33, 124
AllocMem (NumBytes, Use) 553 AreaInfo 124
AllocMem() 157, 203, 319 AreaInfo structure 356
AllocRaster (Width, Height) 528 AreaMove (&RastPort, x, y) 530
AllocRaster() 170, 203, 204, 319 AreaPtSz 126
Amiga libraries 316 ASCII 709
AND 53 ASCII codes 216
Angle parameters 24 AskFont (&RastPort &TextAttr 530
Animate (&AnimOb,&RastPort) 528 AskSoftStyle (&RastPort) 530
Animated bit-planes 80 aspect ratio 20, 23
Animation 21, 55 asynchronous 274
animation 479, 481 AvailFonts (&Buffer, BufferSize,
Type) 550
Animation Components 479
Animation Objects 479 AvailFonts 228
AnimComp 481 AvailFonts structure 393
AnimComp structure 480
AnimComp.AnimBob 481 Backdrop (Layerbackdrop) 197
AnimComp.AnimCRoutine 481 backdrop window 99
AnimComp.NextComp 480 Backup-Register 117
AnimComp.PrevComp 480 bar graph 19
AnimComp.timeset 481 BASIC interpreter 93
AnimComp.XTrans 482 binary numbers 35
AnimComp.YTrans 483 binary pattern mask 36
AnimComps 479, 482 bit pattern 355
AnimOb 481, 482 Bit-map 117,123,166,319,402,417
AnimOb.AnX 482 bit-map structure 321
PAGE 593
-----------------------------------------------------------------------------
bit-planes 46,80,81,149,319,355 CloseScreen(&Screen) 551
402,415 CloseWindow(&Window) 551
Bitmap 149,344 CLS statement 41
Bitmap Offset 153 CMOVE 495, 497
Blitter 52, 349, 399, 400, 465 Collision mask 76
Blitter objects 465 collision 440
BltBitMap 278, 400, 530 collision control 456, 466
BltBitMapRastPort 531 collision detection 496
BltClear (&Memory, NumBytes, Flags) collisions 456, 458, 484
531 CollMask 456, 466, 467
BltClear 399 COLOR statement 33
BltTemplate 407, 412, 532 color 382
bmap file 87 color components 382
Bob.BobComp 480 color cycling 44, 479
Bob.SaveBuffer 477 color depth 4
BOBISCOMP 480 color map 318
bobs 55,85,458,465,466,467,468, color pens 339
476, 479, 484 color registers 4
BOBVSpritee.Depth 466 ColorMap 153, 344
bold print 215 ColorMap structure 318
border color 347 ColorPattern 134
borderless window 99 colors 69
BorderLine 456, 466 COMPLEMENT 125, 340
brush effect 9 constant 503
byte field 95 ConvertFD 87
Copper 153,180,185,452,495
C language 315 Copper list1 53,169,174,181,317,
CEND 497 323,384,382,455,477,495,496,542
ChangeSprite 436, 532 Copper programming 435
Character spacing 128 CreateUpFrontLayer 190,203
Character width 127 cursor 126
CharData 235,412 CWAIT 496,497
charLoc 235
checkmark 69,105 damage list 195
CHR$(0) 100 DBuffPacket 477
CIRCLE statement 24,30 DECLARE FUNCTION LIBRARY 90
CIRCLE 20 DEFINT 36
ClearEOL(&RastPort) 533 Delay (Time) 553
ClearPointer 109 DeleteLayer 190,204
ClearScreen(&RastPort) 533 Depth 69
ClipBlit 402, 533 DIM instruction 36
ClipRect 192, 194 Disk fonts 221
CLOSE 50 diskfont.bmap 87
Close gadget 99 diskfont.libraries 550
CloseFont (&TextFont) 533 Diskfont.library 221
CloseLibrary (&BasePointer) 554 DiskFontBase functions 550
CloseRequest 199 DisownBlitter() 534
PAGE 594
-----------------------------------------------------------------------------
DisplayBeep (&Screen) 551 Font Data 216
DMA 451 Font kern 217
DoCollision 457,464,534 Font Style Flags 390
dos.bmap 87 font 213
doScroll 205 font reader 237
Doulbe Buffering 476,477 font style 392
double buffered displays 423 fonts 219,234,391
double buffering 175 Fore/background gadget 99
Double Buffering Off 180 FreeColorMap(&ColorMap) 535
Double Buffering On 179 FreeColorMap() 170
DragBar 99 FreeCopList(&CopList) 536
Draw() 332,534 FreeMem(&Memory,Size) 554
DrawGList 204 FreeMem() 157,204
DrawEllipse 534 FreeRaster() 170, 204, 536
DrawGList 477,535 FreeSprite(SprNumber) 536
Drawing color 124 FreeSprite (Status) 436
Drawing Mode 125 FreeVPortCopLists(&ViewPort) 537
drawing 69 FreeVPortCopList() 170
drawing pens 341 function plotter 12
Drawmode 340
Dual Playfield mode 422 gadget structure 103
DUALPF flag 422 GEL 464
DUALPF mode 155, 477 GEL list 464, 527
dualplayfield 476 GELGONE 464
GelsInfo 124
Eddi II 56 GelsInfo structure 483
ellipsoids 3 GelsInfo.lastcolor 452
ERASE 50 Genlock Video 155
exec.bmap 87 GET 46, 71
exec_lib 87 GetColorMap (NumberColors) 537
Exit (ReturnValue) 553 GetColorMap 170, 174
EXOR 340 GetMsg (&Port) 554
Extra Halfbrite 155 GetRGB4 537
EXTRA_HALFBRITE 418 Getsprite 436, 452, 537
GfxBase 316
fd 67 GfxBase routines 527
fill 30, 347 GfxBase structure 324
fill modes 357 GimmeZeroZero PArameters 105
fill patterns 354 GimmeZeroZero windows 99,101
filled rectangles 17 graphic cursor 9
First ClipRect 192 graphic elements(GELS) 465
First window 115 graphic library 141
FIags 194 graphic primitives 122,129,381
flags 72, 116 graphic.library 316, 345
Flood (&RastPort,Mode,x,y) 535 graphics.bmap 87
Flood function 347 graphics_lib.fd 87
Font attribute 215 Guru Mediation 93,400
PAGE 595
-----------------------------------------------------------------------------
Halfbrite 156, 320, 418 Inverting graphics 52
HalfBriteOff 160 IODRPReg 259
HalfBriteOn 160 IODRPReg structure 261
HAM 155, 320
HAM mode 161, 419, 421 JAM1 341
hardcopies 259 JAM2 341
Hardcopy 1 262
Hardcopy III 268,271 Kickstart 316
Hardcopy II 265
Hardcopy V 274 LACE flag 415
hardware registers 181 Lattice V3.10 compiler 315
hardware sprites 435 Layer 315
hardware sprites 451 Layer data structure 191
hexadecimal 35 Layer backdrop 196
Hi-res 155 LayerInfo 117
hi-res mode 15 Layers 188
hi-resolution graphics 1 layers libraries 190
Hitmask 457 layers.bmap 87
hold-and-modify 161,419 layers_lib 87
Layersimple 196
I/O Dump RastPort Request 259 Layersmart 196
IDCMP FIags 104 layersuper 194, 196
IFF 279 LIBRARY CLOSE 88
ILBM files 291 LIBRARY statement 88
ILBM graphic 280 library 87, 527
include files 503 LINE 10,19,30
InitArea 538 Line pattern 126
InitBitMap 538 LoadRGB4 170, 174, 540
InitBitMap() 170,204 LoadView(&View) 323,541
InitCop() 181,182 LoadView 170,174
InitGels 538 Lock-Fields 194
InitMasks(&VSprite) 539 Locklayer 194
InitRastPort (&RastPort) 539 long field 95
InitTmpRas 539 MakeDoubleBuffer 179
InitView(&View) 540 MakeScreen (&Screen) 552
InitView 170, 173 MakeVPort(&View,&ViewPort) 541
InitVPort(&ViewPort) 540 MakeVPort 174, 323
InitVPort 170, 174 MakeVPort() 170
INPUT 50 MeMask 457
Interchange File Format 279 menu header 100
Interlaced mode 155,414 Message 251
Intuition 93 MESSAGE port 104,195,260
Intuition.Screen 476 message ports 195
intuition.bmap 87 Messages 195
intuition_lib 87 Minterms 237,401
IntuitionBase routines 476 ModifyIDCMP 552
INVERSVID 125, 341
PAGE 596
-----------------------------------------------------------------------------
Modulo 216, 412 Paint-1024 program instructions
311
MoirE patterns 10 PAL systems 4
MOUSE function 2 palette 41, 42, 43, 80, 318, 382
mouse coordinates 97, 116 parameters 4
mouse pointer 106 PATTERN 35, 129
MOVE 180 Patterned areas 34, 35
Move (&RastPort, X, Y) 541 PEEK 95
Move() 141 PEEKL 95
MoveSprite 541 PEEKW 95
MoveWindow 109 pentagram 32
MrgCop (&View) 542 PFBA 155
MrgCop 170,174 pixel 1
multi-colored patterns 140,355 PlaneOnOff 82
PlanePick 81
NewWindow structure 345 POINT statement 7
Next screen 115 Pointer to Window 206
Next ViewPort 153,168 POKE 95
NextSeq 480 POKEL 95
NTSC video 4 POKEW 95
Polydraw 543
Preferences 390
OBJECT statement 74
OBJECT-SHAPE 56,71 PRESET 3,6
OBJECT.AX/Y 74 PrevSeq 480
OBJECT.CLIP 78,79 printer.device 259
OBJECT.HIT 76,79 proportional font 217
OBJECT.ON 74 PSET 1,6
OBJECT.PRIORITY 79 pseudo menus 15
OBJECT.SHAPE 74 PUT 46,71
OBJECT.START 74 PUT-PRESET 53
OBJECT.VX/Y 74 PUT-PSET 53
OBJECT.X/Y 74
OBJEDIT program 56 quix 11
ON ERROR GOTO 16
OPEN 50 RasInfo 167
OpenDiskFont (&TextAttr) 551 RasInfo Block 154
OpenFont (&TextAttr) 542 RasInfo structure 322,476
OpenFont 391 RastPort 100, 117, 122, 148, 192
344, 412
OpenLibrary 554
OpenLibrary 316 RastPort border 101
OpenScreen (&NewScreen) 552 RastPort structure 122,123,188
323
OPTION BASE 38 ReadPixel (&RastPort, X, Y) 543
OR 53 ReadPixel 90
Overlay Flag 75 rectangle 127,349
Overscan 414 RectFill 543
OwnBlitter() 542 refresh mode 99
relative address 9, 30
PAINT 27,30 ReMakeDisplay 157,160,477,552
PAGE 597
-----------------------------------------------------------------------------
RemFont (&TextFont) 544 SetWindowTitles 204,205
RemIBob 544 Shadow mask 75
RemVSprite(&VSprite) 544 Simple Refresh (Layersimple) 196
ReplyMsg (&Port) 555 SimpleSprite structure 435
ReplyPort 278 SizeWindow 111
Requester Handling 100 sizing gadget 96,99
requester 180 SKIP 180
resolution 413 Smart Refresh (Layersmart) 196
ReThinkDisplay() 553 Smart refresh 99
RINGTRIGGER 481 Software Failure 400
RingXTrans 483 SortGList (&RastPort) 548
RingYTrans 483 SortGList 455
ROM routines 316 SprColor 85,454
ROM versions 316 Sprite collisions 440
sprite 55
SADD 88 sprite image 104
SaveBack flag 72 SPRITE ATTACHED 439
SaveBob 75 SpriteData structure 439
SAveBuffer 477 Sprites 155,435,438,439,495,496
Scaling 16 STEP 9
Screen dimensions 116 structAnimComp 505
Screen Structure 115,120 struct AnimOb 506
screen 68 struct AreaInfo 508
screen colors 117 struct AvailFonts 508
screen gadgets 117 struct AvailFontsHeader 508
screen title 105 struct BitMap 508
Screen/Intuition 114 struct Bob 509
ScreenByte 118 struct ColorMap 511
Screenhere 118 struct Custom 511
Scrolling 195 structDBuffPacket 511
ScrollLayer() 203,205 struct GelsInfo 512
ScrollRaster 544 struct GfxBase 511
Screen 118 struct IntuiMessage 513
ScrollVPort (&ViewPort) 545 struct IntuitionBase 513
SetAPen (&RastPort
Colorregister) 545 struct NewScreen 515
SetBPen(&RastPort,
Colorregiter 545 struct NewWindow 513
SetCollision 546 struct RasInfo 519
SetColllision 484 struct RastPort 516
SetDrMd(&RastPort Mode) 546 struct Screen 519
SetDrMd 125,141 struct SimpleSprite 520
SetFont (&RastPort, &Font) 546 struct TextAttr 520
SetPointer 106 struct TextFont 521
SetRast (&RastPort,
Colorregister) 547 struct View 521
SetRast 204 struct ViewPort 522
SetRG4CM 547 struct VSprite 523
SetRGB4 547 struct Window 525
SetSoftSlyle 548
PAGE 598
-----------------------------------------------------------------------------
StyleEnable 392 View structure 173
Superbit 99 ViewAddress 168
Superbilmap (Layersuper) 196 ViewPort 117,151,166,188,317,323,
Superbitmap 194, 204, 293 344, 381, 413
Superbitmap Paint Program 294 ViewPort Modes 153
SuperClipRect 194 ViewPort structure 153, 318
supergraphic 211 ViewPort 345
SWAP-assignments 40 VP_HIDE 155, 435
switch element 103 VSprite 459
synchronous 274 VSprite flag 464,466
system components 212 VSprite structure 456,466,453
system crash 90 VSprite variables 467
systEm data structure 212 VSprite.OldX 477
system libraries 88 VSprite.OldY 477
Vspritess 435,451,453,456,458,465,
Text 548 467, 495
Textheight 127
text length 389 WAIT 180
text styles 144 WaitBlit () 549
Text() 141 WaitBOVP (&ViewPort) 549
TextAtt 218 WaitTOF 204, 205, 549
TextAttr structure 390, 393 wd 67
TextFont 214 width table 217
TextFont data Structure 215 WINDOW OUTPUT 95
TextFont structure 220,235,250 Window 93
TextLength 548 Window borders 101
TIMER 29 Window colors 105
timer 481 Window limits 98
timeset 483 Window modes 99
Title text 100 window data structure 96, 120
TmpRas 124 window size 96
TmpRas 207 WINDOW(7) 93, 103
topaz 8 213 WINDOW(8) 122, 214
topaz 9 213 WindowLimits 110
topaz font 221 windows 103, 345
transmit 179 WindowToBack 113
WindowToFront 113
UCopList 181 word field 95
Undefined function values 16 WRITE 50
UnLocklayer 194 Writemask 124
user Copper list 181 WritePixel (&RastPort, X, Y) 550
user data 117 WritePixel (&RastPort, X, Y) 327
UserCopperList 495
XOR 51
VBeamPos() 549
View 167
View 317, 413
PAGE 599
-----------------------------------------------------------------------------
T H E E N D
-----------------------------------------------------------------------------